LOADING

在CentOS / Anolis OS 8上二进制安装Kubernetes(k8s) v1.27.4

部署1年前 (2023)更新 Webmaster
625 0 0

之前介绍了使用kubeadm部署Kubernetes,现在我们使用二进制安装Kubernetes(k8s) v1.27.4。
基础系统环境和containerd的配置与使用kubeadm安装一致,可以参看使用kubeadm在龙蜥(Anolis) OS 8上部署Kubernetes,这里直接使用配置好的5台主机:

k8s-master01 ➜  ~ cat > /etc/hosts <<EOF
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6


10.69.10.31 k8s-master01
10.69.10.32 k8s-master02
10.69.10.33 k8s-master03
10.69.10.34 k8s-node01
10.69.10.35 k8s-node02
10.69.10.36 lb-vip   #规划分配的虚IP
EOF

目录

k8s与etcd下载及安装

下载安装k8s、etcd文件

仅在master01操作

k8s-master01 ➜  ~ wget https://dl.k8s.io/v1.27.4/kubernetes-server-linux-amd64.tar.gz
k8s-master01 ➜  ~ tar -xf kubernetes-server-linux-amd64.tar.gz  --strip-components=3 -C /usr/local/bin kubernetes/server/bin/kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy}
k8s-master01 ➜  ~ wget https://github.com/etcd-io/etcd/releases/download/v3.5.9/etcd-v3.5.9-linux-amd64.tar.gz
tar -xf etcd*.tar.gz && mv etcd-*/etcd /usr/local/bin/ && mv etcd-*/etcdctl /usr/local/bin/
k8s-master01 ➜  ~ kubelet --version
Kubernetes v1.27.4
k8s-master01 ➜  ~ etcdctl version
etcdctl version: 3.5.9
API version: 3.5

将文件发送至其他节点

Master='k8s-master02 k8s-master03'
Work='k8s-node01 k8s-node02'

# 拷贝master组件
for NODE in $Master; do echo $NODE; scp /usr/local/bin/kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy} $NODE:/usr/local/bin/; scp /usr/local/bin/etcd* $NODE:/usr/local/bin/; done

# 拷贝work组件
for NODE in $Work; do     scp /usr/local/bin/kube{let,-proxy} $NODE:/usr/local/bin/ ; done

# 所有节点执行
mkdir -p /opt/cni/bin

生成证书

下载CloudFlare开源证书管理工具cfssl

k8s-master01 ➜  ~ wget "https://ghproxy.com/https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl_1.6.4_linux_amd64" -O /usr/local/bin/cfssl
k8s-master01 ➜  ~ wget "https://ghproxy.com/https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssljson_1.6.4_linux_amd64" -O /usr/local/bin/cfssljson
k8s-master01 ➜  ~ chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson

在master01节点生成etcd证书

生成etcd CA:

k8s-master01 ➜  ~ cat > etcd-ca-csr.json  << EOF 
{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "etcd",
      "OU": "Etcd Security"
    }
  ],
  "ca": {
    "expiry": "876000h"
  }
}
EOF
k8s-master01 ➜  mkdir -p /etc/etcd/ssl
k8s-master01 ➜  cfssl gencert -initca etcd-ca-csr.json | cfssljson -bare /etc/etcd/ssl/etcd-ca
k8s-master01 ➜  ll /etc/etcd/ssl/
total 12K
drwxr-xr-x 2 root root   67 Aug  7 21:03 .
drwxr-xr-x 3 root root   17 Aug  7 20:48 ..
-rw-r--r-- 1 root root 1.1K Aug  7 21:03 etcd-ca.csr
-rw------- 1 root root 1.7K Aug  7 21:03 etcd-ca-key.pem
-rw-r--r-- 1 root root 1.3K Aug  7 21:03 etcd-ca.pem

生成etcd证书:

k8s-master01 ➜  cat > ca-config.json << EOF 
{
  "signing": {
    "default": {
      "expiry": "876000h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "876000h"
      }
    }
  }
}
EOF
mkdir /etc/etcd/ssl -p
k8s-master01 ➜ cat > etcd-csr.json << EOF
{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "etcd",
      "OU": "Etcd Security"
    }
  ]
}
EOF
k8s-master01 ➜  cfssl gencert \
   -ca=/etc/etcd/ssl/etcd-ca.pem \
   -ca-key=/etc/etcd/ssl/etcd-ca-key.pem \
   -config=ca-config.json \
   -hostname=127.0.0.1,k8s-master01,k8s-master02,k8s-master03,10.69.10.31,10.69.10.32,10.69.10.33,fd82:2013:0:1::31,fd82:2013:0:1::32,fd82:2013:0:1::33,::1 \
   -profile=kubernetes \
   etcd-csr.json | cfssljson -bare /etc/etcd/ssl/etcd

将Etcd证书复制到其他节点:

Master='k8s-master02 k8s-master03'
for NODE in $Master; do ssh $NODE "mkdir -p /etc/etcd/ssl"; for FILE in etcd-ca-key.pem  etcd-ca.pem  etcd-key.pem  etcd.pem; do scp /etc/etcd/ssl/${FILE} $NODE:/etc/etcd/ssl/${FILE}; done; done

在master01节点生成k8s集群证书

所有证书存放目录

k8s-master01 ➜  mkdir -p /etc/kubernetes/pki

生成根证书

k8s-master01 ➜  cat > ca-csr.json   << EOF 
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "Kubernetes",
      "OU": "Kubernetes-manual"
    }
  ],
  "ca": {
    "expiry": "876000h"
  }
}
EOF
k8s-master01 ➜  cfssl gencert -initca ca-csr.json | cfssljson -bare /etc/kubernetes/pki/ca

生成apiserver证书

10.96.0.1是service网段的第一个地址,10.69.10.36为高可用vip地址。fd82::是IPv6地址,没有IPv6可删除 :

k8s-master01 ➜  cat > apiserver-csr.json << EOF 
{
  "CN": "kube-apiserver",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "Kubernetes",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF
k8s-master01 ➜ cfssl gencert   \
-ca=/etc/kubernetes/pki/ca.pem   \
-ca-key=/etc/kubernetes/pki/ca-key.pem   \
-config=ca-config.json   \
-hostname=10.96.0.1,10.69.10.36,127.0.0.1,kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.default.svc.cluster.local,s1.k8s.webmaster.me,s2.k8s.webmaster.me,s3.k8s.webmaster.me,s4.k8s.webmaster.me,s5.k8s.webmaster.me,apiserver.k8s.webmaster.me,10.69.10.31,10.69.10.32,10.69.10.33,10.69.10.34,10.69.10.35,10.69.10.36,10.69.10.37,10.69.10.38,10.69.10.39,fd82:2013:0:1::31,fd82:2013:0:1::32,fd82:2013:0:1::33,fd82:2013:0:1::34,fd82:2013:0:1::35,fd82:2013:0:1::36,fd82:2013:0:1::37,fd82:2013:0:1::38,fd82:2013:0:1::39,fd82:2013:0:1::40,::1 \
-profile=kubernetes   apiserver-csr.json | cfssljson -bare /etc/kubernetes/pki/apiserver

生成apiserver聚合证书

k8s-master01 ➜ cat > front-proxy-ca-csr.json  << EOF 
{
  "CN": "kubernetes",
  "key": {
     "algo": "rsa",
     "size": 2048
  },
  "ca": {
    "expiry": "876000h"
  }
}
EOF
k8s-master01 ➜ cat > front-proxy-client-csr.json  << EOF 
{
  "CN": "front-proxy-client",
  "key": {
     "algo": "rsa",
     "size": 2048
  }
}
EOF
k8s-master01 ➜ cfssl gencert -initca front-proxy-ca-csr.json | cfssljson -bare /etc/kubernetes/pki/front-proxy-ca 
k8s-master01 ➜ cfssl gencert  \
-ca=/etc/kubernetes/pki/front-proxy-ca.pem   \
-ca-key=/etc/kubernetes/pki/front-proxy-ca-key.pem   \
-config=ca-config.json   \
-profile=kubernetes   front-proxy-client-csr.json | cfssljson -bare /etc/kubernetes/pki/front-proxy-client
# 此处有一个警告,可以忽略

生成controller-manage的证书

k8s-master01 ➜ cat > manager-csr.json << EOF
{
  "CN": "system:kube-controller-manager",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "system:kube-controller-manager",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF
k8s-master01 ➜ cfssl gencert \
   -ca=/etc/kubernetes/pki/ca.pem \
   -ca-key=/etc/kubernetes/pki/ca-key.pem \
   -config=ca-config.json \
   -profile=kubernetes \
   manager-csr.json | cfssljson -bare /etc/kubernetes/pki/controller-manager
2023/08/08 14:41:03 [INFO] generate received request
2023/08/08 14:41:03 [INFO] received CSR
2023/08/08 14:41:03 [INFO] generating key: rsa-2048
2023/08/08 14:41:03 [INFO] encoded CSR
2023/08/08 14:41:03 [INFO] signed certificate with serial number 648599378407428848563643923459757490745898166295
2023/08/08 14:41:03 [WARNING] 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").

设置集群项

k8s-master01 ➜ kubectl config set-cluster kubernetes \
     --certificate-authority=/etc/kubernetes/pki/ca.pem \
     --embed-certs=true \
     --server=https://10.69.10.36:9443 \
     --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
Cluster "kubernetes" set.

# 设置上下文
k8s-master01 ➜ kubectl config set-context system:kube-controller-manager@kubernetes \
    --cluster=kubernetes \
    --user=system:kube-controller-manager \
    --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
Context "system:kube-controller-manager@kubernetes" created.

#设置用户项
k8s-master01 ➜ kubectl config set-credentials system:kube-controller-manager \
     --client-certificate=/etc/kubernetes/pki/controller-manager.pem \
     --client-key=/etc/kubernetes/pki/controller-manager-key.pem \
     --embed-certs=true \
     --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
User "system:kube-controller-manager" set.

#设置默认环境
k8s-master01 ➜ kubectl config use-context system:kube-controller-manager@kubernetes \
     --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
Switched to context "system:kube-controller-manager@kubernetes".

生成scheduler证书


k8s-master01 ➜ cat > scheduler-csr.json << EOF 
{
  "CN": "system:kube-scheduler",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "system:kube-scheduler",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF
k8s-master01 ➜ cfssl gencert \
   -ca=/etc/kubernetes/pki/ca.pem \
   -ca-key=/etc/kubernetes/pki/ca-key.pem \
   -config=ca-config.json \
   -profile=kubernetes \
   scheduler-csr.json | cfssljson -bare /etc/kubernetes/pki/scheduler
2023/08/08 14:56:22 [INFO] generate received request
2023/08/08 14:56:22 [INFO] received CSR
2023/08/08 14:56:22 [INFO] generating key: rsa-2048
2023/08/08 14:56:22 [INFO] encoded CSR
2023/08/08 14:56:22 [INFO] signed certificate with serial number 275856789624972026461098745964707820685935005676
2023/08/08 14:56:22 [WARNING] 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").

设置集群项

k8s-master01 ➜ kubectl config set-cluster kubernetes \
     --certificate-authority=/etc/kubernetes/pki/ca.pem \
     --embed-certs=true \
     --server=https://10.69.10.36:9443 \
     --kubeconfig=/etc/kubernetes/scheduler.kubeconfig
Cluster "kubernetes" set.
k8s-master01 ➜ kubectl config set-credentials system:kube-scheduler \
     --client-certificate=/etc/kubernetes/pki/scheduler.pem \
     --client-key=/etc/kubernetes/pki/scheduler-key.pem \
     --embed-certs=true \
     --kubeconfig=/etc/kubernetes/scheduler.kubeconfig
User "system:kube-scheduler" set.
k8s-master01 ➜ kubectl config set-context system:kube-scheduler@kubernetes \
     --cluster=kubernetes \
     --user=system:kube-scheduler \
     --kubeconfig=/etc/kubernetes/scheduler.kubeconfig
Context "system:kube-scheduler@kubernetes" created.
k8s-master01 ➜ kubectl config use-context system:kube-scheduler@kubernetes \
     --kubeconfig=/etc/kubernetes/scheduler.kubeconfig
Switched to context "system:kube-scheduler@kubernetes".

生成admin证书

k8s-master01 ➜ cat > admin-csr.json << EOF 
{
  "CN": "admin",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "system:masters",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF
k8s-master01 ➜ cfssl gencert \
   -ca=/etc/kubernetes/pki/ca.pem \
   -ca-key=/etc/kubernetes/pki/ca-key.pem \
   -config=ca-config.json \
   -profile=kubernetes \
   admin-csr.json | cfssljson -bare /etc/kubernetes/pki/admin
2023/08/08 15:02:27 [INFO] generate received request
2023/08/08 15:02:27 [INFO] received CSR
2023/08/08 15:02:27 [INFO] generating key: rsa-2048
2023/08/08 15:02:27 [INFO] encoded CSR
2023/08/08 15:02:27 [INFO] signed certificate with serial number 599163309096743852908050259591931132239411947877
2023/08/08 15:02:27 [WARNING] 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").

设置集群项

k8s-master01 ➜ kubectl config set-cluster kubernetes     \
  --certificate-authority=/etc/kubernetes/pki/ca.pem     \
  --embed-certs=true     \
  --server=https://10.69.10.36:9443     \
  --kubeconfig=/etc/kubernetes/admin.kubeconfig
Cluster "kubernetes" set.
k8s-master01 ➜ kubectl config set-credentials kubernetes-admin  \
  --client-certificate=/etc/kubernetes/pki/admin.pem     \
  --client-key=/etc/kubernetes/pki/admin-key.pem     \
  --embed-certs=true     \
  --kubeconfig=/etc/kubernetes/admin.kubeconfig
User "kubernetes-admin" set.
k8s-master01 ➜ kubectl config set-context kubernetes-admin@kubernetes    \
  --cluster=kubernetes     \
  --user=kubernetes-admin     \
  --kubeconfig=/etc/kubernetes/admin.kubeconfig
Context "kubernetes-admin@kubernetes" created.
k8s-master01 ➜ kubectl config use-context kubernetes-admin@kubernetes  --kubeconfig=/etc/kubernetes/admin.kubeconfig
Switched to context "kubernetes-admin@kubernetes".

创建kube-proxy证书

k8s-master01 ➜ cat > kube-proxy-csr.json  << EOF
{
  "CN": "system:kube-proxy",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "system:kube-proxy",
      "OU": "Kubernetes-manual"
    }
  ]
}
EOF
k8s-master01 ➜ cfssl gencert \
   -ca=/etc/kubernetes/pki/ca.pem \
   -ca-key=/etc/kubernetes/pki/ca-key.pem \
   -config=ca-config.json \
   -profile=kubernetes \
   kube-proxy-csr.json | cfssljson -bare /etc/kubernetes/pki/kube-proxy
2023/08/08 15:08:23 [INFO] generate received request
2023/08/08 15:08:23 [INFO] received CSR
2023/08/08 15:08:23 [INFO] generating key: rsa-2048
2023/08/08 15:08:23 [INFO] encoded CSR
2023/08/08 15:08:23 [INFO] signed certificate with serial number 232531878463289736054702372626782366131589497755
2023/08/08 15:08:23 [WARNING] 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").

设置集群项

k8s-master01 ➜ kubectl config set-cluster kubernetes     \
  --certificate-authority=/etc/kubernetes/pki/ca.pem     \
  --embed-certs=true     \
  --server=https://10.69.10.36:9443     \
  --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
Cluster "kubernetes" set.
k8s-master01 ➜ kubectl config set-credentials kube-proxy  \
  --client-certificate=/etc/kubernetes/pki/kube-proxy.pem     \
  --client-key=/etc/kubernetes/pki/kube-proxy-key.pem     \
  --embed-certs=true     \
  --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
User "kube-proxy" set.
k8s-master01 ➜ kubectl config set-context kube-proxy@kubernetes    \
  --cluster=kubernetes     \
  --user=kube-proxy     \
  --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
Context "kube-proxy@kubernetes" created.
k8s-master01 ➜ kubectl config use-context kube-proxy@kubernetes  --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
Switched to context "kube-proxy@kubernetes".

创建ServiceAccount Key


k8s-master01 ➜ openssl genrsa -out /etc/kubernetes/pki/sa.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
..................+++++
...+++++
e is 65537 (0x010001)
k8s-master01 ➜ openssl rsa -in /etc/kubernetes/pki/sa.key -pubout -out /etc/kubernetes/pki/sa.pub
writing RSA key

将证书发送到其他master节点

Master='k8s-master02 k8s-master03'
for NODE in $Master; do 
	ssh $NODE "mkdir -p /etc/kubernetes/pki/";
	for FILE in $(ls /etc/kubernetes/pki | grep -v etcd); do
	  scp /etc/kubernetes/pki/${FILE} $NODE:/etc/kubernetes/pki/${FILE};
	done;
	for FILE in admin.kubeconfig controller-manager.kubeconfig scheduler.kubeconfig; do
	  scp /etc/kubernetes/${FILE} $NODE:/etc/kubernetes/${FILE}; 
	done; 
done

查看证书

总计生成了26个证书文件

k8s-master01 ➜  ~ ll /etc/kubernetes/pki/
total 108K
drwxr-xr-x 2 root root 4.0K Aug  8 15:24 .
drwxr-xr-x 3 root root  106 Aug  8 15:24 ..
-rw-r--r-- 1 root root 1.1K Aug  8 15:24 admin.csr
-rw------- 1 root root 1.7K Aug  8 15:24 admin-key.pem
-rw-r--r-- 1 root root 1.5K Aug  8 15:24 admin.pem
-rw-r--r-- 1 root root 1.8K Aug  8 15:24 apiserver.csr
-rw------- 1 root root 1.7K Aug  8 15:24 apiserver-key.pem
-rw-r--r-- 1 root root 2.2K Aug  8 15:24 apiserver.pem
-rw-r--r-- 1 root root 1.1K Aug  8 15:24 ca.csr
-rw------- 1 root root 1.7K Aug  8 15:24 ca-key.pem
-rw-r--r-- 1 root root 1.4K Aug  8 15:24 ca.pem
-rw-r--r-- 1 root root 1.1K Aug  8 15:24 controller-manager.csr
-rw------- 1 root root 1.7K Aug  8 15:24 controller-manager-key.pem
-rw-r--r-- 1 root root 1.5K Aug  8 15:24 controller-manager.pem
-rw-r--r-- 1 root root  940 Aug  8 15:24 front-proxy-ca.csr
-rw------- 1 root root 1.7K Aug  8 15:24 front-proxy-ca-key.pem
-rw-r--r-- 1 root root 1.1K Aug  8 15:24 front-proxy-ca.pem
-rw-r--r-- 1 root root  903 Aug  8 15:24 front-proxy-client.csr
-rw------- 1 root root 1.7K Aug  8 15:24 front-proxy-client-key.pem
-rw-r--r-- 1 root root 1.2K Aug  8 15:24 front-proxy-client.pem
-rw-r--r-- 1 root root 1.1K Aug  8 15:24 kube-proxy.csr
-rw------- 1 root root 1.7K Aug  8 15:24 kube-proxy-key.pem
-rw-r--r-- 1 root root 1.5K Aug  8 15:24 kube-proxy.pem
-rw------- 1 root root 1.7K Aug  8 15:24 sa.key
-rw-r--r-- 1 root root  451 Aug  8 15:24 sa.pub
-rw-r--r-- 1 root root 1.1K Aug  8 15:24 scheduler.csr
-rw------- 1 root root 1.7K Aug  8 15:24 scheduler-key.pem
-rw-r--r-- 1 root root 1.5K Aug  8 15:24 scheduler.pem
k8s-master01 ➜  ~ ls /etc/kubernetes/pki/ |wc -l
26

k8s系统组件配置

etcd配置

master01配置

cat > /etc/etcd/etcd.config.yml << EOF 
name: 'k8s-master01'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://10.69.10.31:2380'
listen-client-urls: 'https://10.69.10.31:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors:
initial-advertise-peer-urls: 'https://10.69.10.31:2380'
advertise-client-urls: 'https://10.69.10.31:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy:
discovery-srv:
initial-cluster: 'k8s-master01=https://10.69.10.31:2380,k8s-master02=https://10.69.10.32:2380,k8s-master03=https://10.69.10.33:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
peer-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
debug: false
log-package-levels:
log-outputs: [default]
force-new-cluster: false
EOF

master02配置

cat > /etc/etcd/etcd.config.yml << EOF 
name: 'k8s-master02'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://10.69.10.32:2380'
listen-client-urls: 'https://10.69.10.32:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors:
initial-advertise-peer-urls: 'https://10.69.10.32:2380'
advertise-client-urls: 'https://10.69.10.32:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy:
discovery-srv:
initial-cluster: 'k8s-master01=https://10.69.10.31:2380,k8s-master02=https://10.69.10.32:2380,k8s-master03=https://10.69.10.33:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
peer-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
debug: false
log-package-levels:
log-outputs: [default]
force-new-cluster: false
EOF

master03配置

cat > /etc/etcd/etcd.config.yml << EOF 
name: 'k8s-master03'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://10.69.10.33:2380'
listen-client-urls: 'https://10.69.10.33:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors:
initial-advertise-peer-urls: 'https://10.69.10.33:2380'
advertise-client-urls: 'https://10.69.10.33:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy:
discovery-srv:
initial-cluster: 'k8s-master01=https://10.69.10.31:2380,k8s-master02=https://10.69.10.32:2380,k8s-master03=https://10.69.10.33:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
peer-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
debug: false
log-package-levels:
log-outputs: [default]
force-new-cluster: false
EOF

创建系统的service

以下在所有master节点操作

创建etcd.service

cat > /usr/lib/systemd/system/etcd.service << EOF

[Unit]
Description=Etcd Service
Documentation=https://coreos.com/etcd/docs/latest/
After=network.target

[Service]
Type=notify
ExecStart=/usr/local/bin/etcd --config-file=/etc/etcd/etcd.config.yml
Restart=on-failure
RestartSec=10
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
Alias=etcd3.service

EOF

连接etcd证书并启动服务

mkdir /etc/kubernetes/pki/etcd
ln -s /etc/etcd/ssl/* /etc/kubernetes/pki/etcd/
systemctl daemon-reload
systemctl enable --now etcd

查看etcd状态

k8s-master01 ➜ export ETCDCTL_API=3
k8s-master01 ➜ etcdctl --endpoints="10.69.10.33:2379,10.69.10.32:2379,10.69.10.31:2379" --cacert=/etc/kubernetes/pki/etcd/etcd-ca.pem --cert=/etc/kubernetes/pki/etcd/etcd.pem --key=/etc/kubernetes/pki/etcd/etcd-key.pem  endpoint status --write-out=table
+------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|     ENDPOINT     |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 10.69.10.33:2379 | b94a51895c30f1d8 |   3.5.9 |   20 kB |     false |      false |         2 |          9 |                  9 |        |
| 10.69.10.32:2379 | df26027ebcf77ffe |   3.5.9 |   20 kB |     false |      false |         2 |          9 |                  9 |        |
| 10.69.10.31:2379 | 91783f6bc6a30ab8 |   3.5.9 |   20 kB |      true |      false |         2 |          9 |                  9 |        |
+------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

配置负载均衡

安装keepalived和haproxy(3台master节点都执行)

yum -y install keepalived haproxy

配置haproxy

修改haproxy配置文件(3台master节点都执行)

mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.backup
cat >/etc/haproxy/haproxy.cfg<<"EOF"
global
 maxconn 2000
 ulimit-n 16384
 log 127.0.0.1 local0 err
 stats timeout 30s

defaults
 log global
 mode http
 option httplog
 timeout connect 5000
 timeout client 50000
 timeout server 50000
 timeout http-request 15s
 timeout http-keep-alive 15s


frontend monitor-in
 bind *:33305
 mode http
 option httplog
 monitor-uri /monitor

frontend k8s-master
 bind 0.0.0.0:9443
 bind 127.0.0.1:9443
 mode tcp
 option tcplog
 tcp-request inspect-delay 5s
 default_backend k8s-master


backend k8s-master
 mode tcp
 option tcplog
 option tcp-check
 balance roundrobin
 default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
 server  k8s-master01  10.69.10.31:6443 check
 server  k8s-master02  10.69.10.32:6443 check
 server  k8s-master03  10.69.10.33:6443 check
EOF

配置keepalived节点

Master01配置keepalived master节点

k8s-master01 ➜ mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.backup
k8s-master01 ➜ cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived

global_defs {
    router_id LVS_DEVEL
}
vrrp_script chk_apiserver {
    script "/etc/keepalived/check_apiserver.sh"
    interval 5
    weight -5
    fall 2
    rise 1
}
vrrp_instance VI_1 {
    state MASTER
    # 注意网卡名
    interface enp1s0
    mcast_src_ip 10.69.10.31
    virtual_router_id 51
    priority 100
    nopreempt
    advert_int 2
    authentication {
        auth_type PASS
        auth_pass K8SHA_KA_AUTH
    }
    virtual_ipaddress {
        10.69.10.36
    }
    track_script {
      chk_apiserver
} }

EOF

Master02配置keepalived backup节点

cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived

global_defs {
    router_id LVS_DEVEL
}
vrrp_script chk_apiserver {
    script "/etc/keepalived/check_apiserver.sh"
    interval 5 
    weight -5
    fall 2
    rise 1

}
vrrp_instance VI_1 {
    state BACKUP
    # 注意网卡名
    interface enp1s0
    mcast_src_ip 10.69.10.32
    virtual_router_id 51
    priority 80
    nopreempt
    advert_int 2
    authentication {
        auth_type PASS
        auth_pass K8SHA_KA_AUTH
    }
    virtual_ipaddress {
        10.69.10.36
    }
    track_script {
      chk_apiserver 
} }

EOF

Master03配置keepalived backup节点

cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived

global_defs {
    router_id LVS_DEVEL
}
vrrp_script chk_apiserver {
    script "/etc/keepalived/check_apiserver.sh"
    interval 5 
    weight -5
    fall 2
    rise 1

}
vrrp_instance VI_1 {
    state BACKUP
    # 注意网卡名
    interface enp1s0
    mcast_src_ip 10.69.10.33
    virtual_router_id 51
    priority 50
    nopreempt
    advert_int 2
    authentication {
        auth_type PASS
        auth_pass K8SHA_KA_AUTH
    }
    virtual_ipaddress {
        10.69.10.36
    }
    track_script {
      chk_apiserver 
} }

EOF

健康检查脚本

健康检查脚本配置(3台master节点都执行)

cat >  /etc/keepalived/check_apiserver.sh << EOF
#!/bin/bash

err=0
for k in \$(seq 1 3)
do
    check_code=\$(pgrep haproxy)
    if [[ \$check_code == "" ]]; then
        err=\$(expr \$err + 1)
        sleep 1
        continue
    else
        err=0
        break
    fi
done

if [[ \$err != "0" ]]; then
    echo "systemctl stop keepalived"
    /usr/bin/systemctl stop keepalived
    exit 1
else
    exit 0
fi
EOF

chmod +x /etc/keepalived/check_apiserver.sh

启动haproxy/keepalived服务

systemctl daemon-reload
systemctl enable --now haproxy
systemctl enable --now keepalived

测试高可用

k8s-master03 ➜  ~ ping 10.69.10.36
PING 10.69.10.36 (10.69.10.36) 56(84) bytes of data.
64 bytes from 10.69.10.36: icmp_seq=1 ttl=64 time=0.546 ms
64 bytes from 10.69.10.36: icmp_seq=2 ttl=64 time=0.487 ms
64 bytes from 10.69.10.36: icmp_seq=3 ttl=64 time=0.383 ms
64 bytes from 10.69.10.36: icmp_seq=4 ttl=64 time=0.426 ms
^C
--- 10.69.10.36 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3112ms
rtt min/avg/max/mdev = 0.383/0.460/0.546/0.065 ms
k8s-master03 ➜  ~ telnet 10.69.10.36 9443
Trying 10.69.10.36...
Connected to 10.69.10.36.
Escape character is '^]'.
Connection closed by foreign host.

k8s组件配置

所有k8s节点创建以下目录

mkdir -p /etc/kubernetes/manifests/ /etc/systemd/system/kubelet.service.d /var/lib/kubelet /var/log/kubernetes

创建apiserver

master01节点配置

cat > /usr/lib/systemd/system/kube-apiserver.service << EOF

[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-apiserver \
      --v=2  \
      --allow-privileged=true  \
      --bind-address=0.0.0.0  \
      --secure-port=6443  \
      --advertise-address=10.69.10.31 \
      --service-cluster-ip-range=10.96.0.0/12,fd00::/108  \
      --service-node-port-range=30000-32767  \
      --etcd-servers=https://10.69.10.31:2379,https://10.69.10.32:2379,https://10.69.10.33:2379 \
      --etcd-cafile=/etc/etcd/ssl/etcd-ca.pem  \
      --etcd-certfile=/etc/etcd/ssl/etcd.pem  \
      --etcd-keyfile=/etc/etcd/ssl/etcd-key.pem  \
      --client-ca-file=/etc/kubernetes/pki/ca.pem  \
      --tls-cert-file=/etc/kubernetes/pki/apiserver.pem  \
      --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem  \
      --kubelet-client-certificate=/etc/kubernetes/pki/apiserver.pem  \
      --kubelet-client-key=/etc/kubernetes/pki/apiserver-key.pem  \
      --service-account-key-file=/etc/kubernetes/pki/sa.pub  \
      --service-account-signing-key-file=/etc/kubernetes/pki/sa.key  \
      --service-account-issuer=https://kubernetes.default.svc.cluster.local \
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname  \
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota  \
      --authorization-mode=Node,RBAC  \
      --enable-bootstrap-token-auth=true  \
      --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem  \
      --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem  \
      --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem  \
      --requestheader-allowed-names=aggregator  \
      --requestheader-group-headers=X-Remote-Group  \
      --requestheader-extra-headers-prefix=X-Remote-Extra-  \
      --requestheader-username-headers=X-Remote-User \
      --enable-aggregator-routing=true
Restart=on-failure
RestartSec=10s
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

EOF

master02节点配置

cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-apiserver \
      --v=2  \
      --allow-privileged=true  \
      --bind-address=0.0.0.0  \
      --secure-port=6443  \
      --advertise-address=10.69.10.32 \
      --service-cluster-ip-range=10.96.0.0/12,fd00::/108  \
      --service-node-port-range=30000-32767  \
      --etcd-servers=https://10.69.10.31:2379,https://10.69.10.32:2379,https://10.69.10.33:2379 \
      --etcd-cafile=/etc/etcd/ssl/etcd-ca.pem  \
      --etcd-certfile=/etc/etcd/ssl/etcd.pem  \
      --etcd-keyfile=/etc/etcd/ssl/etcd-key.pem  \
      --client-ca-file=/etc/kubernetes/pki/ca.pem  \
      --tls-cert-file=/etc/kubernetes/pki/apiserver.pem  \
      --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem  \
      --kubelet-client-certificate=/etc/kubernetes/pki/apiserver.pem  \
      --kubelet-client-key=/etc/kubernetes/pki/apiserver-key.pem  \
      --service-account-key-file=/etc/kubernetes/pki/sa.pub  \
      --service-account-signing-key-file=/etc/kubernetes/pki/sa.key  \
      --service-account-issuer=https://kubernetes.default.svc.cluster.local \
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname  \
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota  \
      --authorization-mode=Node,RBAC  \
      --enable-bootstrap-token-auth=true  \
      --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem  \
      --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem  \
      --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem  \
      --requestheader-allowed-names=aggregator  \
      --requestheader-group-headers=X-Remote-Group  \
      --requestheader-extra-headers-prefix=X-Remote-Extra-  \
      --requestheader-username-headers=X-Remote-User \
      --enable-aggregator-routing=true

Restart=on-failure
RestartSec=10s
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

EOF

master03节点配置

cat > /usr/lib/systemd/system/kube-apiserver.service  << EOF

[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-apiserver \
      --v=2  \
      --allow-privileged=true  \
      --bind-address=0.0.0.0  \
      --secure-port=6443  \
      --advertise-address=10.69.10.33 \
      --service-cluster-ip-range=10.96.0.0/12,fd00::/108  \
      --service-node-port-range=30000-32767  \
      --etcd-servers=https://10.69.10.31:2379,https://10.69.10.32:2379,https://10.69.10.33:2379 \
      --etcd-cafile=/etc/etcd/ssl/etcd-ca.pem  \
      --etcd-certfile=/etc/etcd/ssl/etcd.pem  \
      --etcd-keyfile=/etc/etcd/ssl/etcd-key.pem  \
      --client-ca-file=/etc/kubernetes/pki/ca.pem  \
      --tls-cert-file=/etc/kubernetes/pki/apiserver.pem  \
      --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem  \
      --kubelet-client-certificate=/etc/kubernetes/pki/apiserver.pem  \
      --kubelet-client-key=/etc/kubernetes/pki/apiserver-key.pem  \
      --service-account-key-file=/etc/kubernetes/pki/sa.pub  \
      --service-account-signing-key-file=/etc/kubernetes/pki/sa.key  \
      --service-account-issuer=https://kubernetes.default.svc.cluster.local \
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname  \
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota  \
      --authorization-mode=Node,RBAC  \
      --enable-bootstrap-token-auth=true  \
      --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem  \
      --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem  \
      --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem  \
      --requestheader-allowed-names=aggregator  \
      --requestheader-group-headers=X-Remote-Group  \
      --requestheader-extra-headers-prefix=X-Remote-Extra-  \
      --requestheader-username-headers=X-Remote-User \
      --enable-aggregator-routing=true

Restart=on-failure
RestartSec=10s
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

EOF

启动apiserver

在所有master节点执行:

systemctl daemon-reload
systemctl enable --now kube-apiserver
systemctl restart kube-apiserver
systemctl status kube-apiserver

配置Controller-Manager service

创建系统service文件

所有master节点都用相同的配置,172.16.0.0/12为pod网段,按需求设置。

cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF

[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-controller-manager \
      --v=2 \
      --bind-address=0.0.0.0 \
      --root-ca-file=/etc/kubernetes/pki/ca.pem \
      --cluster-signing-cert-file=/etc/kubernetes/pki/ca.pem \
      --cluster-signing-key-file=/etc/kubernetes/pki/ca-key.pem \
      --service-account-private-key-file=/etc/kubernetes/pki/sa.key \
      --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig \
      --leader-elect=true \
      --use-service-account-credentials=true \
      --node-monitor-grace-period=40s \
      --node-monitor-period=5s \
      --controllers=*,bootstrapsigner,tokencleaner \
      --allocate-node-cidrs=true \
      --service-cluster-ip-range=10.96.0.0/12,fd00::/108 \
      --cluster-cidr=172.16.0.0/12,fc00::/48 \
      --node-cidr-mask-size-ipv4=24 \
      --node-cidr-mask-size-ipv6=64 \
      --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem

Restart=always
RestartSec=10s

[Install]
WantedBy=multi-user.target

EOF

启动kube-controller-manager

启动并查看状态

systemctl daemon-reload
systemctl enable --now kube-controller-manager
systemctl restart kube-controller-manager
systemctl status kube-controller-manager

配置kube-scheduler service

创建系统service文件

所有master节点配置,且配置相同

cat > /usr/lib/systemd/system/kube-scheduler.service << EOF

[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-scheduler \
      --v=2 \
      --bind-address=0.0.0.0 \
      --leader-elect=true \
      --kubeconfig=/etc/kubernetes/scheduler.kubeconfig

Restart=always
RestartSec=10s

[Install]
WantedBy=multi-user.target

EOF

启动kube-scheduler

启动并查看服务状态

systemctl daemon-reload
systemctl enable --now kube-scheduler
systemctl restart kube-scheduler
systemctl status kube-scheduler

TLS Bootstrapping配置

在master01上配置

kubectl config set-cluster kubernetes     \
--certificate-authority=/etc/kubernetes/pki/ca.pem     \
--embed-certs=true     --server=https://10.69.10.36:9443     \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig

kubectl config set-credentials tls-bootstrap-token-user     \
--token=c8ad9c.2e4d610cf3e7426e \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig

kubectl config set-context tls-bootstrap-token-user@kubernetes     \
--cluster=kubernetes     \
--user=tls-bootstrap-token-user     \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig

kubectl config use-context tls-bootstrap-token-user@kubernetes     \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig

mkdir -p /root/.kube ; cp /etc/kubernetes/admin.kubeconfig /root/.kube/config

查看集群状态

k8s-master01 ➜ kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS    MESSAGE   ERROR
controller-manager   Healthy   ok
etcd-0               Healthy
etcd-2               Healthy
etcd-1               Healthy
scheduler            Healthy   ok

创建bootstrap.secret

k8s-master01 ➜ cat > bootstrap.secret.yaml << EOF 
apiVersion: v1
kind: Secret
metadata:
  name: bootstrap-token-c8ad9c
  namespace: kube-system
type: bootstrap.kubernetes.io/token
stringData:
  description: "The default bootstrap token generated by 'kubelet '."
  token-id: c8ad9c
  token-secret: 2e4d610cf3e7426e
  usage-bootstrap-authentication: "true"
  usage-bootstrap-signing: "true"
  auth-extra-groups:  system:bootstrappers:default-node-token,system:bootstrappers:worker,system:bootstrappers:ingress
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubelet-bootstrap
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:node-bootstrapper
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:bootstrappers:default-node-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: node-autoapprove-bootstrap
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:bootstrappers:default-node-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: node-autoapprove-certificate-rotation
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:nodes
---
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/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: kube-apiserver
EOF

k8s-master01 ➜ kubectl create -f bootstrap.secret.yaml
secret/bootstrap-token-c8ad9c created
clusterrolebinding.rbac.authorization.k8s.io/kubelet-bootstrap created
clusterrolebinding.rbac.authorization.k8s.io/node-autoapprove-bootstrap created
clusterrolebinding.rbac.authorization.k8s.io/node-autoapprove-certificate-rotation created
clusterrole.rbac.authorization.k8s.io/system:kube-apiserver-to-kubelet created
clusterrolebinding.rbac.authorization.k8s.io/system:kube-apiserver created

node节点配置

在master01上将证书复制到node节点

cd /etc/kubernetes/
 
for NODE in k8s-master02 k8s-master03 k8s-node01 k8s-node02; do ssh $NODE mkdir -p /etc/kubernetes/pki; for FILE in pki/ca.pem pki/ca-key.pem pki/front-proxy-ca.pem bootstrap-kubelet.kubeconfig kube-proxy.kubeconfig; do scp /etc/kubernetes/$FILE $NODE:/etc/kubernetes/${FILE}; done; done

kubelet配置

配置kubelet service

在所有节点配置:

cat > /usr/lib/systemd/system/kubelet.service << EOF

[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=containerd.service
Requires=containerd.service

[Service]
ExecStart=/usr/local/bin/kubelet \
    --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig  \
    --kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
    --config=/etc/kubernetes/kubelet-conf.yml \
    --container-runtime-endpoint=unix:///run/containerd/containerd.sock  \
    --node-labels=node.kubernetes.io/node=

[Install]
WantedBy=multi-user.target
EOF

创建kubelet的配置文件

在所有节点配置:

cat > /etc/kubernetes/kubelet-conf.yml <<EOF
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
authentication:
  anonymous:
    enabled: false
  webhook:
    cacheTTL: 2m0s
    enabled: true
  x509:
    clientCAFile: /etc/kubernetes/pki/ca.pem
authorization:
  mode: Webhook
  webhook:
    cacheAuthorizedTTL: 5m0s
    cacheUnauthorizedTTL: 30s
cgroupDriver: systemd
cgroupsPerQOS: true
clusterDNS:
- 10.96.0.10
clusterDomain: cluster.local
containerLogMaxFiles: 5
containerLogMaxSize: 10Mi
contentType: application/vnd.kubernetes.protobuf
cpuCFSQuota: true
cpuManagerPolicy: none
cpuManagerReconcilePeriod: 10s
enableControllerAttachDetach: true
enableDebuggingHandlers: true
enforceNodeAllocatable:
- pods
eventBurst: 10
eventRecordQPS: 5
evictionHard:
  imagefs.available: 15%
  memory.available: 100Mi
  nodefs.available: 10%
  nodefs.inodesFree: 5%
evictionPressureTransitionPeriod: 5m0s
failSwapOn: true
fileCheckFrequency: 20s
hairpinMode: promiscuous-bridge
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 20s
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80
imageMinimumGCAge: 2m0s
iptablesDropBit: 15
iptablesMasqueradeBit: 14
kubeAPIBurst: 10
kubeAPIQPS: 5
makeIPTablesUtilChains: true
maxOpenFiles: 1000000
maxPods: 110
nodeStatusUpdateFrequency: 10s
oomScoreAdj: -999
podPidsLimit: -1
registryBurst: 10
registryPullQPS: 5
resolvConf: /etc/resolv.conf
rotateCertificates: true
runtimeRequestTimeout: 2m0s
serializeImagePulls: true
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 4h0m0s
syncFrequency: 1m0s
volumeStatsAggPeriod: 1m0s
EOF

启动kubelet

systemctl daemon-reload
systemctl enable --now kubelet
systemctl restart kubelet
systemctl status kubelet

kube-proxy配置

将kubeconfig发送至其他节点

for NODE in k8s-master02 k8s-master03 k8s-node01 k8s-node02; do scp /etc/kubernetes/kube-proxy.kubeconfig $NODE:/etc/kubernetes/kube-proxy.kubeconfig; done

配置kube-proxy的service文件

所有k8s节点添加kube-proxy的service文件

cat >  /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-proxy \
  --config=/etc/kubernetes/kube-proxy.yaml \
  --v=2

Restart=always
RestartSec=10s

[Install]
WantedBy=multi-user.target

EOF

添加kube-proxy的配置

所有k8s节点添加kube-proxy的配置

cat > /etc/kubernetes/kube-proxy.yaml << EOF
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
clientConnection:
  acceptContentTypes: ""
  burst: 10
  contentType: application/vnd.kubernetes.protobuf
  kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
  qps: 5
clusterCIDR: 172.16.0.0/12,fc00::/48
configSyncPeriod: 15m0s
conntrack:
  max: null
  maxPerCore: 32768
  min: 131072
  tcpCloseWaitTimeout: 1h0m0s
  tcpEstablishedTimeout: 24h0m0s
enableProfiling: false
healthzBindAddress: 0.0.0.0:10256
hostnameOverride: ""
iptables:
  masqueradeAll: false
  masqueradeBit: 14
  minSyncPeriod: 0s
  syncPeriod: 30s
ipvs:
  masqueradeAll: true
  minSyncPeriod: 5s
  scheduler: "rr"
  syncPeriod: 30s
kind: KubeProxyConfiguration
metricsBindAddress: 127.0.0.1:10249
mode: "ipvs"
nodePortAddresses: null
oomScoreAdj: -999
portRange: ""
udpIdleTimeout: 250ms

EOF

启动kube-proxy

 systemctl daemon-reload
 systemctl restart kube-proxy
 systemctl enable --now kube-proxy
 systemctl status kube-proxy

安装网络插件

安装配置Calico

配置calico

下载calico部署文件

wget https://raw.githubusercontent.com/projectcalico/calico/master/manifests/calico-typha.yaml -O calico.yaml

更改calico网段,纯IPv4配置:

vim calico.yaml
# calico-config ConfigMap处
    "ipam": {
        "type": "calico-ipam",
    },
    - name: IP
      value: "autodetect"

    - name: CALICO_IPV4POOL_CIDR
      value: "172.16.0.0/12"

IPv4+IPv6双栈配置:

vim calico.yaml
# calico-config ConfigMap处
    "ipam": {
        "type": "calico-ipam",
        "assign_ipv4": "true",
        "assign_ipv6": "true"
    },
    - name: IP
      value: "autodetect"

    - name: IP6
      value: "autodetect"

    - name: CALICO_IPV4POOL_CIDR
      value: "172.16.0.0/12"

    - name: CALICO_IPV6POOL_CIDR
      value: "fc00::/48"

    - name: FELIX_IPV6SUPPORT
      value: "true"

国内服务器可使用国内的docker仓库:

sed -i "s#docker.io/calico/#m.daocloud.io/docker.io/calico/#g" calico.yaml 

部署calico

kubectl apply -f calico.yaml

查看集群状态

k8s-master01 ➜ kubectl  get node
NAME           STATUS   ROLES    AGE    VERSION
k8s-master01   Ready    <none>   30m   v1.27.4
k8s-master02   Ready    <none>   30m   v1.27.4
k8s-master03   Ready    <none>   30m   v1.27.4
k8s-node01     Ready    <none>   30m   v1.27.4
k8s-node02     Ready    <none>   30m   v1.27.4
k8s-master01 ➜ kubectl describe node | grep Runtime
  Container Runtime Version:  containerd://1.7.2
  Container Runtime Version:  containerd://1.7.2
  Container Runtime Version:  containerd://1.7.2
  Container Runtime Version:  containerd://1.7.2
  Container Runtime Version:  containerd://1.7.2
k8s-master01 ➜ kubectl  get pod -A
NAMESPACE     NAME                                      READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-8787c9999-wvcpf   1/1     Running   0          6m
kube-system   calico-node-5ctd6                         1/1     Running   0          6m
kube-system   calico-node-rq27f                         1/1     Running   0          6m
kube-system   calico-node-rwbmz                         1/1     Running   0          6m
kube-system   calico-node-rzfpd                         1/1     Running   0          6m
kube-system   calico-node-sdzkb                         1/1     Running   0          6m
kube-system   calico-typha-76544b4c45-qnqmw             1/1     Running   0          6m

安装CoreDNS

以下步骤只在master01操作

安装Helm 3

k8s-master01 ➜ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
k8s-master01 ➜ chmod 700 get_helm.sh
k8s-master01 ➜ ./get_helm.sh
Downloading https://get.helm.sh/helm-v3.12.2-linux-amd64.tar.gz
Verifying checksum... Done.
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm
k8s-master01 ➜ helm list
NAME	NAMESPACE	REVISION	UPDATED	STATUS	CHART	APP VERSION

下载CoreDNS

k8s-master01 ➜ helm repo add coredns https://coredns.github.io/helm
k8s-master01 ➜ helm pull coredns/coredns
k8s-master01 ➜ tar xvf coredns-*.tgz

修改配置

修改IP地址

k8s-master01 ➜ cat coredns/values.yaml | grep clusterIP:
  clusterIP: "10.96.0.10"

国内服务器可使用国内的docker仓库:

sed -i "s#coredns/#m.daocloud.io/docker.io/coredns/#g" values.yaml
sed -i "s#registry.k8s.io/#m.daocloud.io/registry.k8s.io/#g" values.yaml

部署coredns

helm install  coredns ./coredns/ -n kube-system

检查dns服务

k8s-master01 ➜ kubectl get pod -n kube-system
NAME                                      READY   STATUS    RESTARTS   AGE
calico-kube-controllers-8787c9999-wvcpf   1/1     Running   0          10m
calico-node-5ctd6                         1/1     Running   0          10m
calico-node-rq27f                         1/1     Running   0          10m
calico-node-rwbmz                         1/1     Running   0          10m
calico-node-rzfpd                         1/1     Running   0          10m
calico-node-sdzkb                         1/1     Running   0          10m
calico-typha-76544b4c45-qnqmw             1/1     Running   0          10m
coredns-coredns-67f64d7dc9-gprsp          1/1     Running   0          118s

安装Metrics Server

以下步骤只在master01操作

下载配置Metrics-server

下载高可用版本,并修改关键性配置:

wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/high-availability.yaml
vim high-availability.yaml

---
# 1
defaultArgs:
  - --cert-dir=/tmp
  - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
  - --kubelet-use-node-status-port
  - --metric-resolution=15s
  - --kubelet-insecure-tls
  - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem
  - --requestheader-username-headers=X-Remote-User
  - --requestheader-group-headers=X-Remote-Group
  - --requestheader-extra-headers-prefix=X-Remote-Extra-

# 2
        volumeMounts:
        - mountPath: /tmp
          name: tmp-dir
        - name: ca-ssl
          mountPath: /etc/kubernetes/pki

# 3
      volumes:
      - emptyDir: {}
        name: tmp-dir
      - name: ca-ssl
        hostPath:
          path: /etc/kubernetes/pki
---

国内服务器可使用国内的docker仓库:

sed -i "s#registry.k8s.io/#m.daocloud.io/registry.k8s.io/#g" *.yaml

部署Metrics-server

kubectl apply -f high-availability.yaml

查看节点资源

k8s-master01 ➜ kubectl  top node
NAME           CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
k8s-master01   171m         8%     1283Mi          68%
k8s-master02   123m         6%     1172Mi          62%
k8s-master03   145m         7%     1164Mi          62%
k8s-node01     78m          3%     607Mi           32%
k8s-node02     73m          3%     591Mi           31%

集群验证

部署pod资源

k8s-master01 ➜ cat<<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - name: busybox
    image: docker.io/library/busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always
EOF
pod/busybox created
k8s-master01 ➜ kubectl  get pod
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   0          35s

解析默认命名空间

用pod解析默认命名空间中的kubernetes

k8s-master01 ➜ kubectl exec  busybox -n default -- nslookup kubernetes
Server:    10.96.0.10
Address 1: 10.96.0.10 coredns-coredns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local

测试跨命名空间是否可以解析

k8s-master01 ➜ kubectl  get svc -A
NAMESPACE     NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
default       kubernetes        ClusterIP   10.96.0.1        <none>        443/TCP         24h
kube-system   calico-typha      ClusterIP   10.106.170.221   <none>        5473/TCP        4h33m
kube-system   coredns-coredns   ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP   44m
kube-system   metrics-server    ClusterIP   10.98.255.190    <none>        443/TCP         27m
k8s-master01 ➜
k8s-master01 ➜ kubectl exec  busybox -n default -- nslookup coredns-coredns.kube-system
Server:    10.96.0.10
Address 1: 10.96.0.10 coredns-coredns.kube-system.svc.cluster.local

Name:      coredns-coredns.kube-system
Address 1: 10.96.0.10 coredns-coredns.kube-system.svc.cluster.local

测试节点联通性

在其他节点上测试联通性,每个节点都必须要能访问Kubernetes的kubernetes svc 443和kube-dns的service 53

k8s-node01 ➜  ~ telnet 10.96.0.1 443
Trying 10.96.0.1...
Connected to 10.96.0.1.
Escape character is '^]'.
^]
telnet> Connection closed.
k8s-node01 ➜  ~ telnet 10.96.0.10 53
Trying 10.96.0.10...
Connected to 10.96.0.10.
Escape character is '^]'.
Connection closed by foreign host.
k8s-node01 ➜  ~ curl 10.96.0.10:53
curl: (52) Empty reply from server

Pod和Pod之前要能通

k8s-master01 ➜ kubectl get pod -owide
NAME      READY   STATUS    RESTARTS   AGE     IP             NODE           NOMINATED NODE   READINESS GATES
busybox   1/1     Running   0          9m39s   172.25.92.66   k8s-master02   <none>           <none>
k8s-master01 ➜
k8s-master01 ➜ kubectl get pod -n kube-system -owide
NAME                                      READY   STATUS    RESTARTS   AGE     IP               NODE           NOMINATED NODE   READINESS GATES
calico-kube-controllers-8787c9999-wvcpf   1/1     Running   0          4h39m   172.25.244.193   k8s-master01   <none>           <none>
calico-node-5ctd6                         1/1     Running   0          4h39m   10.69.10.34      k8s-node01     <none>           <none>
calico-node-rq27f                         1/1     Running   0          4h39m   10.69.10.33      k8s-master03   <none>           <none>
calico-node-rwbmz                         1/1     Running   0          4h39m   10.69.10.35      k8s-node02     <none>           <none>
calico-node-rzfpd                         1/1     Running   0          4h39m   10.69.10.31      k8s-master01   <none>           <none>
calico-node-sdzkb                         1/1     Running   0          4h39m   10.69.10.32      k8s-master02   <none>           <none>
calico-typha-76544b4c45-qnqmw             1/1     Running   0          4h39m   10.69.10.31      k8s-master01   <none>           <none>
coredns-coredns-67f64d7dc9-gprsp          1/1     Running   0          50m     172.18.195.1     k8s-master03   <none>           <none>
metrics-server-7bf65989c5-bh6fv           1/1     Running   0          33m     172.27.14.193    k8s-node02     <none>           <none>
metrics-server-7bf65989c5-pdwmw           1/1     Running   0          33m     172.17.125.1     k8s-node01     <none>           <none>

进入busybox ping其他节点上的pod

k8s-master01 ➜ kubectl exec -ti busybox -- sh
/ # ping 10.69.10.34
PING 10.69.10.34 (10.69.10.34): 56 data bytes
64 bytes from 10.69.10.34: seq=0 ttl=63 time=1.117 ms
64 bytes from 10.69.10.34: seq=1 ttl=63 time=0.687 ms
64 bytes from 10.69.10.34: seq=2 ttl=63 time=0.695 ms
64 bytes from 10.69.10.34: seq=3 ttl=63 time=0.415 ms
^C
--- 10.69.10.34 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.415/0.728/1.117 ms
/ #

多副本测试

创建三个副本,可以看到3个副本分布在不同的节点上

k8s-master01 ➜ cat > deployments.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

EOF
k8s-master01 ➜ kubectl  apply -f deployments.yaml
deployment.apps/nginx-deployment created
k8s-master01 ➜ kubectl get pod -owide
NAME                               READY   STATUS    RESTARTS   AGE   IP              NODE           NOMINATED NODE   READINESS GATES
busybox                            1/1     Running   0          13m   172.25.92.66    k8s-master02   <none>           <none>
nginx-deployment-55f598f8d-25qx9   1/1     Running   0          28s   172.17.125.2    k8s-node01     <none>           <none>
nginx-deployment-55f598f8d-8kvmv   1/1     Running   0          28s   172.18.195.2    k8s-master03   <none>           <none>
nginx-deployment-55f598f8d-dq224   1/1     Running   0          28s   172.27.14.194   k8s-node02     <none>           <none>
# 测试完毕删除
k8s-master01 ➜ kubectl delete -f deployments.yaml
deployment.apps "nginx-deployment" deleted

ingress安装

配置和部署

k8s-master01 ➜ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml

k8s-master01 ➜ kubectl  apply -f deploy.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created

安装cert-manager

添加repo

k8s-master01 ➜ helm repo add jetstack https://charts.jetstack.io
k8s-master01 ➜ helm repo update

helm安装v1.11版本

k8s-master01 ➜ helm install \
 cert-manager jetstack/cert-manager \
 --namespace cert-manager --create-namespace \
 --set ingressShim.defaultIssuerName=letsencrypt-prod \
 --set ingressShim.defaultIssuerKind=ClusterIssuer \
 --set ingressShim.defaultIssuerGroup=cert-manager.io \
 --set installCRDs=true \
 --version v1.11.4

NAME: cert-manager
LAST DEPLOYED: Fri Aug 11 00:29:57 2023
NAMESPACE: cert-manager
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
cert-manager v1.11.4 has been deployed successfully!

In order to begin issuing certificates, you will need to set up a ClusterIssuer
or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).

More information on the different types of issuers and how to configure them
can be found in our documentation:

https://cert-manager.io/docs/configuration/

For information on how to configure cert-manager to automatically provision
Certificates for Ingress resources, take a look at the `ingress-shim`
documentation:

https://cert-manager.io/docs/usage/ingress/

查看安装的cert-manager


k8s-master01 ➜ kubectl get crd | grep cert
certificaterequests.cert-manager.io                   2023-08-10T16:29:58Z
certificates.cert-manager.io                          2023-08-10T16:29:58Z
challenges.acme.cert-manager.io                       2023-08-10T16:29:58Z
clusterissuers.cert-manager.io                        2023-08-10T16:29:58Z
issuers.cert-manager.io                               2023-08-10T16:29:58Z
orders.acme.cert-manager.io                           2023-08-10T16:29:58Z
k8s-master01 ➜ kubectl get po -n cert-manager
NAME                                       READY   STATUS    RESTARTS   AGE
cert-manager-549c8f4dfc-29dkh              1/1     Running   0          5m2s
cert-manager-cainjector-7ffc56d8c5-xs7qv   1/1     Running   0          5m2s
cert-manager-webhook-dcc6cd765-rf8cz       1/1     Running   0          5m2s

安装MetalLB

稍后安装的dashboard使用LoadBalancer模式,为了能正确获取EXTERNAL-IP,需要部署负载均衡服务。

添加repo

k8s-master01 ➜ helm repo add metallb https://metallb.github.io/metallb
k8s-master01 ➜ helm install metallb metallb/metallb

MetalLB 有 Layer2 模式和 BGP 模式,因为 BGP 对路由器有要求,因此我们测试时使用 Layer2 模式。

创建 IPAdressPool

多个实例IP地址池可以共存,并且地址可以由CIDR定义, 按范围分配,并且可以分配IPV4和IPV6地址。

k8s-master01 ➜ cat <<EOF > IPAddressPool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: default
spec:
  addresses:
  # 可分配的 IP 地址,可以指定多个,包括 ipv4、ipv6
  - 10.69.10.51-10.69.10.70
EOF

k8s-master01 ➜ kubectl apply -f IPAddressPool.yaml
ipaddresspool.metallb.io/first-pool created

创建 L2Advertisement

L2 模式不要求将 IP 绑定到网络接口 工作节点。它的工作原理是响应本地网络 arp 请求,以将计算机的 MAC 地址提供给客户端。如果不设置关联到 IPAdressPool,那默认 L2Advertisement 会关联上所有可用的 IPAdressPool。
创建 L2Advertisement,并关联 IPAdressPool:

k8s-master01 ➜ cat <<EOF > L2Advertisement.yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: advertisement.example
  namespace: default
spec:
  ipAddressPools:
  - first-pool #上一步创建的 ip 地址池,通过名字进行关联
EOF
k8s-master01 ➜ kubectl apply -f L2Advertisement.yaml
l2advertisement.metallb.io/advertisement.example created

安装dashboard

添加repo

k8s-master01 ➜ helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
k8s-master01 ➜ helm repo update

helm安装v3版本

k8s-master01 ➜ helm install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard --create-namespace --namespace kubernetes-dashboard \
  --set=app.ingress.hosts="{localhost,kubernetes.dashboard.webmaster.me}" \
  --set=nginx.enabled="false" \
  --set=cert-manager.enabled="false" \
  --set=metrics-server.enabled="false"
NAME: kubernetes-dashboard
LAST DEPLOYED: Fri Aug 11 00:45:19 2023
NAMESPACE: kubernetes-dashboard
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
*************************************************************************************************
*** PLEASE BE PATIENT: Kubernetes Dashboard may need a few minutes to get up and become ready ***
*************************************************************************************************

Congratulations! You have just installed Kubernetes Dashboard in your cluster.

It looks like you already have nginx installed in your cluster. First find the namespace where it is installed and then find its main service name. By default, it should be located in namespace called nginx or nginx-ingress and service name should be nginx-controller.

To access Dashboard run (replace placeholders with actual names):
  kubectl -n <nginx-namespace> port-forward svc/<nginx-service> 8443:443

Dashboard will be available at:
  https://localhost:8443

Looks like you are deploying Kubernetes Dashboard on a custom domain(s).
Please make sure that the ingress configuration is valid.
Dashboard should be accessible on your configured domain(s) soon:
  - https://kubernetes.dashboard.webmaster.me

NOTE: It may take a few minutes for the Ingress IP/Domain to be available.
      It does not apply to local dev Kubernetes installations such as kind, etc.
      You can watch the status using:
        kubectl -n kubernetes-dashboard get ing kubernetes-dashboard -w

创建用户账号

k8s-master01 ➜ kubectl create serviceaccount kube-dashboard-admin-sa -n kubernetes-dashboard
serviceaccount/kube-dashboard-admin-sa created
k8s-master01 ➜ kubectl create clusterrolebinding kube-dashboard-admin-sa \
--clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:kube-dashboard-admin-sa
clusterrolebinding.rbac.authorization.k8s.io/kube-dashboard-admin-sa created
k8s-master01 ➜ kubectl create token kube-dashboard-admin-sa -n kubernetes-dashboard --duration=87600h
eyJhbGciOiJSUzI1NiIsImtpZCI6IncwY0JSRUVKbnZ5YWU3SU5PRkZTMTR5OHhzenMzXzRPSlJjNDVTdjllSzQifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoyMDA3MDQ5MDIxLCJpYXQiOjE2OTE2ODkwMjEsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJrdWJlLWRhc2hib2FyZC1hZG1pbi1zYSIsInVpZCI6IjVkZWM2ODFlLTdiZDEtNDAwMC04MThiLTQ3ZGRkZWZkNzA5NSJ9fSwibmJmIjoxNjkxNjg5MDIxLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6a3ViZS1kYXNoYm9hcmQtYWRtaW4tc2EifQ.1yXJS6jxhr6_ZbWZVV56vQx7c96plB3cddpmx5Vi7fvEhfe6ZU2D3PD8hwlVqktB26KR2qE1jgX8tIFQg-Qw5u7Wy8y6Z7crAosM6k_u6DjMqfV5cD_CoEtuUTsq_09T1t7-LO8neSmgHc7ViV96tbsCsfWtm1vYXXjBWmcw2AAZPibBLO14jpNj_nmNJlTZVYQaBKTA4TIdjaGe-Apof0WCRy4z4ORmipwJCAm9tmOm_YEt2j080P4sdIqDefvYJ14ZfkHT1_dIBSwxKm_BvxSwHP7c0n1kr-nk8CUqwm3PSW3rjo1msyj9iFDSFYKbh675_RoXMnWIKsMBp40Rtw

获取访问IP

查看ingress-nginx服务:

k8s-master01 ➜ kubectl -n ingress-nginx get svc
NAME                                 TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.111.164.184   10.69.10.51   80:30823/TCP,443:31214/TCP   66m
ingress-nginx-controller-admission   ClusterIP      10.98.126.47     <none>        443/TCP                      66m

从服务列表里看到给ingress-nginx-controller自动分配的外部IP是10.69.10.51。

配置hosts

在宿主机或其他需要访问的主机配置hosts:

k8s-master01 ➜ cat >> /etc/hosts <<EOF
10.69.10.51  kubernetes.dashboard.webmaster.me
EOF

访问dashboard

使用浏览器访问https://kubernetes.dashboard.webmaster.me,用上面生成的token登录控制面板:
在CentOS / Anolis OS 8上二进制安装Kubernetes(k8s) v1.27.4

文章内容主要参考abcdocker及其他网络文章,如有侵权请告知。

© 版权声明

相关文章

暂无评论

暂无评论...