使用最新组件,通过二进制方式安装kubernetes-v1.20.8(二)

五 kube-apiserver 服务

  k8s 根证书请求文件【k8s-ca-csr.json】如下:    k8sfk 根证书请求文件【k8s-ca-csr.json】 如下:

       {

  "CN": "kubernetes",

  "key": {

    "algo": "rsa",

    "size": 2048

       }

       }

   kube-apiserver 服务端证书请求文件【k8s-kube-apiserver-csr.json】如下:

  {

  "CN": "api-server",

  "hosts": [

    "127.0.0.1",

    "192.168.1.160",

    "192.168.1.161",

    "192.168.1.162",

    "192.168.1.163",

    "192.168.1.163",

    "192.168.1.165",

    "10.88.0.1",

    "kubernetes",

    "kubernetes.default",

    "kubernetes.default.svc",

    "kubernetes.default.svc.cluster",

    "k8s-cluster-apiserver-lbs",

    "kubernetes.default.svc.cluster.local"

  ],

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "CN",

      "ST": "Guangdong",

      "L": "Dongguan",

      "O": "k8s",

      "OU": "system"

      }

               ]

  }


   kube-apiserver 证书请求配置文件【k8s-config-csr.json】如下:

{

  "signing": {

    "default": {

      "expiry": "43800h"

    },

    "profiles": {

      "k8s": {

        "expiry": "43800h",

        "usages": [

          "signing",

          "key encipherment",

          "server auth",

          "client auth"

            ]

           }

        }

     }

   }

k8s kube-apiserver 聚合服务证书pki(kube-apiserver 上要启动聚合服务才能通过kube-apiserver 代理访问扩展插件比如:metrics),这里聚合服务使用了另外一套独立的ca体系

聚合服务的证书请求配置文件采用的和k8s是一个配置文件【k8s-config-csr.json]

  聚合服务ca的证书请求文件【aggregator-proxy-client-ca-csr.json】为:

{

  "CN": "aggregator-proxy-client-ca",

  "key": {

    "algo": "rsa",

    "size": 2048

     }

  }

  聚合服务证书请求文件【aggregator-proxy-client-client-csr.json】为:

{
  "CN": "aggregator-proxy-client",
  "key": {
    "algo": "rsa",
    "size": 2048
  }
}

   5.1 生成证书

k8s 根证书
cfssl gencert -initca k8s-ca-csr.json

kube-apiserver 证书

cfssl gencert -ca=k8s-ca.pem -ca-key=k8s-ca-key.pem -config=k8s-config-csr.json -profile=k8s k8s-kube-apiserver-csr.json | cfssljson -bare kube-apiserver

聚合服务根证书

cfssl gencert -initca aggregator-proxy-client-ca-csr.json

聚合服务器证书

cfssl gencert -ca=aggregator-proxy-client-ca.pem -ca-key=aggregator-proxy-client-ca-key.pem -config=k8s-config-csr.json -profile=k8s aggregator-proxy-client-client-csr.json |cfssljson -bare aggregator-proxy-client-client


这里描述下kube-apiserver 配置 的证书功能

--tls-cert-file=/var/lib/kubernetes/kube-apiserver.pem                                                       # 用于对外提供服务的服务器证书
--tls-private-key-file=/var/lib/kubernetes/kube-apiserver-key.pem                                    # 服务器证书对应的私钥
--etcd-certfile=/var/lib/kubernetes/etcd-client.pem\                                                          # 用于访问 etcd 的客户端证书
--etcd-keyfile=/var/lib/kubernetes/etcd-client-key .pem                                                   # 用于访问 etcd 的客户端证书的私钥
--kubelet-client-certificate=/var/lib/kubernetes/kube-apiserver-kubelet-client.pem          # 用于访问 kubelet 的客户端证书
--kubelet-client-key=/var/lib/kubernetes/kube-apiserver-kubelet-client-key.pem             #用于访问 kubelet 的客户端证书的私钥
--client-ca-file=/var/lib/kubernetes/cluster-root-ca.pem                           # 用于验证访问 kube-apiserver 的客户端的证书的 CA 根证书
--etcd-cafile=/var/lib/kubernetes/cluster-root-ca.pem                                                      # 用于验证 etcd 服务器证书的 CA 根证书
--kubelet-certificate-authority=/var/lib/kubernetes/cluster-root-ca.pem                            # 用于验证 kubelet 服务器证书的 CA 根证书
--service-account-key-file=/var/lib/kubernetes/service-account.pem                               # 用于验证 service account token 的公钥
--requestheader-client-ca-file=/opt/kubernetes/k8s/ssl/aggregator-proxy-client-ca.pem # 聚合根证书
--proxy-client-cert-file=/opt/kubernetes/k8s/ssl/aggregator-proxy-client-client.pem        # 聚合服务client证书
--proxy-client-key-file=/opt/kubernetes/k8s/ssl/aggregator-proxy-client-client-key.pem  #聚合服务私有证书


 5.2 启动kube-apiserver

通过 https://github.com/kubernetes/kubernetes/releases 下载kubernetes 相关二进制文件 我这里下载了1.20.8 
建立kube-apiserver 放置启动参数文件夹,和证书存放文件夹  mkdir -p /etc/kubernetes 【放置启动参数文件】 mkdir -p /opt/kubernetes 【存放证书文件】mkdir -p /var/log/kubernetes 【存放日志文件】

然后vim kube-apiserver.conf

把下列选项贴出进去:

KUBE_APISERVER_OPTS='--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
  --anonymous-auth=false \
  --bind-address=192.168.1.160 \
  --secure-port=6443 \
  --advertise-address=192.168.1.160 \
  --authorization-mode=Node,RBAC \
  --runtime-config=api/all=true \
  --enable-bootstrap-token-auth \
  --service-cluster-ip-range=10.88.0.0/16 \
  --token-auth-file=/opt/kubernetes/token.csv \
  --service-node-port-range=40000-50000 \
  --tls-cert-file=/opt/kubernetes/k8s/ssl/kube-apiserver.pem  \
  --tls-private-key-file=/opt/kubernetes/k8s/ssl/kube-apiserver-key.pem \
  --client-ca-file=/opt/kubernetes/k8s/ssl/k8s-ca.pem \
  --kubelet-client-certificate=/opt/kubernetes/k8s/ssl/kube-apiserver.pem \
  --kubelet-client-key=/opt/kubernetes/k8s/ssl/kube-apiserver-key.pem \
  --service-account-key-file=/opt/kubernetes/k8s/ssl/service-account.pem \
  --service-account-signing-key-file=/opt/kubernetes/k8s/ssl/service-account-key.pem \
  --service-account-issuer=https://kubernetes.default.svc.cluster.local \
  --etcd-cafile=/opt/kubernetes/etcd/ssl/ca.pem \
  --etcd-certfile=/opt/kubernetes/etcd/ssl/etcd-server.pem \
  --etcd-keyfile=/opt/kubernetes/etcd/ssl/etcd-server-key.pem \
  --etcd-servers=https://192.168.188.88:2379,https://192.168.188.89:2379,https://192.168.188.90:2379 \
  --requestheader-allowed-names=aggregator-proxy-client \
  --requestheader-group-headers=X-Remote-Group \
  --requestheader-username-headers=X-Remote-User \
  --requestheader-extra-headers-prefix=X-Remote-Extra- \
  --enable-aggregator-routing=true \
  --requestheader-client-ca-file=/opt/kubernetes/k8s/ssl/aggregator-proxy-client-ca.pem \
  --proxy-client-cert-file=/opt/kubernetes/k8s/ssl/aggregator-proxy-client-client.pem \
  --proxy-client-key-file=/opt/kubernetes/k8s/ssl/aggregator-proxy-client-client-key.pem \
  --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 \
  --alsologtostderr=true \
  --logtostderr=false \
  --log-dir=/var/log/kubernetes \
  --v=4'


其中 --token-auth-file=/opt/kubernetes/token.csv  

token内容如下

cat > token.csv << EOF
$(head -c 16 /dev/urandom | od -An -t x | tr -d ' '),kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
然后在 /usr/lib/systemd/system 下,建立kube-apiserver.service 文件,内容如下:

[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=etcd.service
Wants=etcd.service
[Service]
EnvironmentFile=-/etc/kubernetes/kube-apiserve.conf
ExecStart=/usr/bin/kube-apiserver $KUBE_APISERVER_OPTS
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target


然后 systemctl --now enable kube-apiserver.service,查看启动是否正常,如果错误,可以通过 systemctl status kube-apiserver.service 或 查看 /var/log/kubernetes 下的日志文件确认问题。
把此文件复制到第二个和第三个主节点 并修改   --bind-address 和 --advertise-address 改成本机ip地址,分别启动服务。

六 kube-controller-manager 服务


kube-controller-manager 和 kube-scheduler 访问kube-apiserver 是通过内置的角色 system:kube-controller-manager 和system:kube-scheduler  来实现的。

基于RBAC的认证,都是从证书的cn或o取得用户名或组,所以生成kuber-controller-manager 和kube-scheduler的证书时候,cn或o的名称之一一定是这个两个内置的角色,

这里,生成证书 的时候,cn的名称使用的system:kube-controller-manager 


 

 6.1 生成kube-controller-manager 证书

   证书请求文件【kube-controller-manager-csr.json】内容:

{

  "CN": "system:kube-controller-manager",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "hosts": [

    "127.0.0.1",

    "192.168.1.160",

    "192.168.1.161",

    "192.168.1.162"

  ],

  "names": [

    {

      "C": "CN",

      "ST": "Guangdong",

      "L": "Dongguan",

      "O": "k8s",

      "OU": "sthmei"

    }

  ]

}


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


生成证书

生成kube-controller-manager 证书:

cfssl gencert -ca=k8s-ca.pem -ca-key=k8s-ca-key.pem -config=k8s-config-csr.json -profile=k8s kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager


6.2 设置kube-controller-manger 访问kube-apiserver 的用户和用户凭证【这里是证书】

attachments-2021-07-3LEYmQYt60f135ddbcb89,jpg                                                                             图1

图1是一个k8s 各主件访问图,注意箭头方向


设置集群参数

[root@master1 work]# kubectl config set-cluster kubernetes --certificate-authority=k8s-ca.pem --embed-certs=true --server=https://172.10.0.20:6443 --kubeconfig=kube-controller-manager.kubeconfig

设置客户端认证参数 这里的用户为:【system:kube-controller-manager】

[root@master1 work]# kubectl config set-credentials system:kube-controller-manager --client-certificate=kube-controller-manager.pem --client-key=kube-controller-manager-key.pem --embed-certs=true --kubeconfig=kube-controller-manager.kubeconfig

设置上下文参数

[root@master1 work]# kubectl config set-context system:kube-controller-manager --cluster=kubernetes --user=system:kube-controller-manager --kubeconfig=kube-controller-manager.kubeconfig

设置默认上下文

[root@master1 work]# kubectl config use-context system:kube-controller-manager --kubeconfig=kube-controller-manager.kubeconfig

6.3 启动kube-controller-manager.service 

配置kube-controller-manager 启动参数文件 vim /etc/kubernetes/

KUBE_CONTROLLER_MANAGER_OPTS="--bind-address=127.0.0.1 \
  --kubeconfig=/opt/kubernetes/k8s/kube-controller-manager.kubeconfig \
  --service-cluster-ip-range=10.88.0.0/16 \
  --cluster-name=kubernetes \
  --cluster-signing-cert-file=/opt/kubernetes/k8s/ssl/k8s-ca.pem \
  --cluster-signing-key-file=/opt/kubernetes/k8s/ssl/k8s-ca-key.pem \
  --allocate-node-cidrs=true \
  --cluster-cidr=10.88.20.0/16 \
  --service-account-private-key-file=/opt/kubernetes/k8s/ssl/service-account-key.pem \
  --leader-elect=true \
 --cluster-signing-duration duration  \
  --feature-gates=RotateKubeletServerCertificate=true \
  --controllers=*,bootstrapsigner,tokencleaner \
  --horizontal-pod-autoscaler-use-rest-clients=true \
  --horizontal-pod-autoscaler-sync-period=10s \
  --tls-cert-file=/opt/kubernetes/k8s/ssl/kube-controller-manager.pem \
  --tls-private-key-file=/opt/kubernetes/k8s/ssl/kube-controller-manager-key.pem \
  --use-service-account-credentials=true \
  --alsologtostderr=true \
  --logtostderr=false \
  --log-dir=/var/log/kubernetes \
  --v=2"

其中--cluster-signing-duration duration 为controller控制 Kublet通过bootstrap 获取证书的有效期,默认是8760h0m0s 也就是一年,这个尽量和其他证书过期时间保持一致

--horizontal-pod-autoscaler-use-rest-clients 在k8s v1.22 中已经废弃

然后编辑 vim /usr/lib/systemd/system/kube-controller-manager.service 文件如下:

[Unit]

Description=Kubernetes Controller Manager

Documentation=https://github.com/kubernetes/kubernetes


[Service]

EnvironmentFile=-/etc/kubernetes/kube-controller-manager.conf

ExecStart=/usr/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS

Restart=on-failure

RestartSec=5


[Install]

WantedBy=multi-user.target


然后 通过 systemctl --now enable kube-controller-service.service

把启动参数文件,启动文件,kube-controller-manager.kubeconfig 文件,证书文件复制到另外两个节点并启动服务。

七 kube-scheduler 服务 

   7.1  生成kube-scheduler 证书,

   k8s中默认有内置clusterrole为 system:kube-scheduler ,并且有一个同名内置clusterrolebinding ,其中的的用户为:system:kube-scheduler,所以生成证书只要cn为“system:kube-scheduler"  即可。

attachments-2021-07-KOVbmaUp60f153026bf8f,png

                                                       图2 

kube-sheduler 【 kube-scheduler-csr.json】 证书请求文件如下:

{

  "CN": "system:kube-scheduler",

  "hosts": [

    "127.0.0.1",

    "192.168.1.160",

    "192.168.1.161",

    "192.168.1.162"

  ],

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "CN",

      "ST": "Guangdong",

      "L": "Dongguan",

      "O": "k8s",

      "OU": "system"

    }

  ]

}


生成kube-controller-manager 证书:

cfssl gencert -ca=k8s-ca.pem -ca-key=k8s-ca-key.pem -config=k8s-config-csr.json -profile=k8s kube-scheduler-csr.json | cfssljson -bare kube-scheduler

 7.2 创建kube-scheduler的kubeconfig

设置集群参数

[root@master1 work]# kubectl config set-cluster kubernetes --certificate-authority=k8s-ca.pem --embed-certs=true --server=https://172.10.0.20:6443 --kubeconfig=kube-scheduler.kubeconfig

设置客户端认证参数

[root@master1 work]# kubectl config set-credentials system:kube-scheduler --client-certificate=kube-scheduler.pem --client-key=kube-scheduler-key.pem --embed-certs=true --kubeconfig=kube-scheduler.kubeconfig

设置上下文参数

[root@master1 work]# kubectl config set-context system:kube-scheduler --cluster=kubernetes --user=system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig

设置默认上下文

[root@master1 work]# kubectl config use-context system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig



7.3 启动kube-scheduler.service 

kube-scheduler 启动参数文件:


cat /etc/kubernetes/kube-scheduler.conf

KUBE_SCHEDULER_OPTS="--address=127.0.0.1 \

--kubeconfig=/opt/kubernetes/k8s/kube-scheduler.kubeconfig \

--leader-elect=true \

--alsologtostderr=true \

--logtostderr=false \

--log-dir=/var/log/kubernetes \

--v=2

systemd 启动文件:

cat /usr/lib/system/system

[Unit]

Description=Kubernetes Scheduler

Documentation=https://github.com/kubernetes/kubernetes


[Service]

EnvironmentFile=-/etc/kubernetes/kube-scheduler.conf

ExecStart=/usr/bin/kube-scheduler $KUBE_SCHEDULER_OPTS

Restart=on-failure

RestartSec=5


[Install]

WantedBy=multi-user.target


然后 systemctl --now enable kube-scheduer.service

把启动参数文件,启动文件,kube-scheduler.kubeconfig 文件,证书文件复制到另外两个节点并启动服务。


证书文件和证书请求配置文件可以这里下载


八  部署containerd 容器运行时

  8.1 k8s 从 v1.20.x 开始,开始不推荐使用docker 容器运行时,淘汰docker是一个趋势,本次二进制安装的v1.20.8 版本使用 containerd 作为容器。

attachments-2021-07-Hkec4i5p60f166c97c0ad,jpg

                                                            图3

从图中可以看到,去掉docker,可以使调用栈更短


 8.2 安装containerd ,本次使用最新的containerd 为1.5.2

通过页面 https://containerd.io/downloads/ 下载最新的二进制文件
 

 wget https://github.com/containerd/containerd/releases/download/v1.5.2/containerd-1.5.2-linux-amd64.tar.gz


下载下来的文件解压后,有四个文件 containerd containerd-shim containerd-shim-runc-v1 containerd-shim-runc-v2

下载下来的文件没有包含runc文件,可以通过yum install -y runc (我的系统为centos 8.2 ) 通过yum安装的为最新的runc,如果不是,可以到runc官网下载它的二进制文件。

把接下的文件copy到/usr/bin 目录,然后 chmod +x container*  给予可执行权限。

新建containerd 配置文件目录和 运行目录 mkdir -p  /etc/containerd   和运行目录  /var/run/containerd/ 

通过 containerd config default >/etc/containerd/config.toml 生成默认的配置文件。
 默认需要修改两个地方:
[plugins."io.containerd.grpc.v1.cri"] 下面的

sandbox_image = "k8s.gcr.io/pause:3.5"  修改为:sandbox_image = "ima.pub/infra/pause:3.5" 
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
下SystemdCgroup = false 修改为 SystemdCgroup = true

k8s.gcr.io 镜像国内下载不了。  我的镜像这里为私有镜像,默认需要账号和密码才能访问,可以使用
kubectl create secret docker-registry containerd-secrets-pull --docker-username=xxx --docker-password=yyy --docker-server=ima.pub -n kube-system
来创建一个,这里创建的 containerd-secrects-pull 只在 kube-system 下生效。 注:containerd 对于docker login 生成 .dock/config.json 文件也是支持的,这个安全性更好,通过
上面命令创建的secrect文件,只是简单把账号密码 base64编码,很容易泄露,建议使用docker login 生成的 config.json 文件。

启动containerd

cat /usr/lib/systemd/system/containerd.service

# Copyright The containerd Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target

[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStartPre=-/bin/mkdir -p /sys/fs/cgroup/hugetlb/systemd/system.slice/kubelet.service
ExecStartPre=-/bin/mkdir -p /sys/fs/cgroup/blkio/systemd/system.slice/kubelet.service
ExecStartPre=-/bin/mkdir -p /sys/fs/cgroup/cpuset/systemd/system.slice/kubelet.service
ExecStartPre=-/bin/mkdir -p /sys/fs/cgroup/devices/systemd/system.slice/kubelet.service
ExecStartPre=-/bin/mkdir -p /sys/fs/cgroup/net_cls,net_prio/systemd/system.slice/kubelet.service
ExecStartPre=-/bin/mkdir -p /sys/fs/cgroup/perf_event/systemd/system.slice/kubelet.service
ExecStartPre=-/bin/mkdir -p /sys/fs/cgroup/cpu,cpuacct/systemd/system.slice/kubelet.service
ExecStartPre=-/bin/mkdir -p /sys/fs/cgroup/freezer/systemd/system.slice/kubelet.service
ExecStartPre=-/bin/mkdir -p /sys/fs/cgroup/memory/systemd/system.slice/kubelet.service
ExecStartPre=-/bin/mkdir -p /sys/fs/cgroup/pids/systemd/system.slice/kubelet.service
ExecStartPre=-/bin/mkdir -p /sys/fs/cgroup/systemd/systemd/system.slice/kubelet.service
ExecStart=/usr/bin/containerd

Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999

[Install]
WantedBy=multi-user.target

然后 systemctl --now enable containerd.service   

最后把containerd* 四个文件和配置文件copy到所有机器上的对应位置 

master节点在本教程中需要安装cni网络,而calico是通过pod部署的,所以控制节点上也要安装containerd

九  kubelet

kubelet 是worker节点上pod,负责pod创建,驱逐,监控,和kube-apiserver 通信。
kubelet和kube-apiserver 通讯是双向的,kubelet 既要和apiserver通讯,apiserver也要查询kublet服务器,比如通过kubectl exec pod   kubectl logs pod 等,都去需要通过apiserver通讯。
 

9.1 设置kubelet 和kube-apiserver 通讯的凭证 

为了方便给每个worker节点签发证书,这里使用了 bootstrap 方式动态签发证书,签发过程如下:
attachments-2021-07-yrXRKwmf60f2739ea01b2,png
                                                                           图4

所以 使用kubelet启动的认证凭证就是那个token,这个token文件在kube-apiserver 中有加载。这里生成kubelet 访问kube-apserver 的kubeconfig 文件,其中的
生成token方式:
cat > token.csv << EOF $(head -c 16 /dev/urandom | od -An -t x | tr -d ' '),kubelet-bootstrap,10001,"system:kubelet-bootstrap" EOF

[root@master1 work]# BOOTSTRAP_TOKEN=$(awk -F "," '{print $1}' /opt/kubernetes/token.csv)
设置集群参数
[root@master1 work]# kubectl config set-cluster kubernetes --certificate-authority=k8s-ca.pem --embed-certs=true --server=https://172.10.0.20:6443 --kubeconfig=kubelet-bootstrap.kubeconfig
设置客户端认证参数
[root@master1 work]# kubectl config set-credentials kubelet-bootstrap --token=${BOOTSTRAP_TOKEN} --kubeconfig=kubelet-bootstrap.kubeconfig
设置上下文参数
[root@master1 work]# kubectl config set-context default --cluster=kubernetes --user=kubelet-bootstrap --kubeconfig=kubelet-bootstrap.kubeconfig
设置默认上下文
[root@master1 work]# kubectl config use-context default --kubeconfig=kubelet-bootstrap.kubeconfig
创建角色绑定
[root@master1 work]# kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap

k8s 默认用户组里面没有 kubelet-bootstrap ,需要使用标红的命令创建,如果不创建,则会报如下错误:

Jan 17 03:17:30 k8-master-01 kubelet[949369]: E0117 03:17:30.412783  949369 server.go:294] "Failed to run kubelet" err="failed to run Kubelet: cannot create certificate signing request: certificatesigningrequests.certificates.k8s.io is forbidden: User \"kubelet-bootstrap\" cannot create resource \"certificatesigningrequests\" in API group \"certificates.k8s.io\" at the cluster scope"
Jan 17 03:17:30 k8-master-01 systemd[1]: kubelet.service: Main process exited, code=exited, status=1/FAILURE


这里给kubelet bootstrap 绑定的k8s 内置角色为:system:node-bootstrapper 这个角色权限如下

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  creationTimestamp: "2021-07-05T12:09:50Z"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:node-bootstrapper
  resourceVersion: "107"
  uid: 6fc13148-5095-4f85-a728-b3c74279f683
rules:
- apiGroups:
  - certificates.k8s.io
  resources:
  - certificatesigningrequests
  verbs:
  - create
  - get
  - list
  - watch

这个角色只能对证书进行 create get  list watch 等操作,不能操作其他资源。

9.2 kubelet 启动配置文件,很多参数文件,官方建议通过yaml和json格式文件加载

{
  "kind": "KubeletConfiguration",
  "apiVersion": "kubelet.config.k8s.io/v1beta1",
  "authentication": {
    "x509": {
      "clientCAFile": "/opt/kubernetes/k8s/ssl/k8s-ca.pem"
    },
    "webhook": {
      "enabled": true,
      "cacheTTL": "2m0s"
    },
    "anonymous": {
      "enabled": false
    }
  },
  "authorization": {
    "mode": "Webhook",
    "webhook": {
      "cacheAuthorizedTTL": "5m0s",
      "cacheUnauthorizedTTL": "30s"
    }
  },
  "address": "192.168.1.160",
  "port": 10250,
  "readOnlyPort": 10255,
  "cgroupDriver": "systemd",
  "hairpinMode": "promiscuous-bridge",
  "serializeImagePulls": false,
  "featureGates": {
    "RotateKubeletClientCertificate": true,
    "RotateKubeletServerCertificate": true
  },
  "evictionHard": {
    "memory.available": "300Mi",
    "imagefs.available": "<5%",
    "nodefs.available": "<5%"
  },

  "clusterDomain": "cluster.local.",
  "clusterDNS": [
    "10.88.0.10"
  ]
}


9.3 kubelet 启动文件

cat /usr/lib/systemd/system/kubelet.service

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

[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/usr/bin/kubelet \
  --bootstrap-kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig \
  --cert-dir=/opt/kubernetes/k8s/ssl \
  --kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
  --config=/opt/kubernetes/kubelet.json \
  --container-runtime=remote \
  --container-runtime-endpoint=unix:///run/containerd/containerd.sock \
  --network-plugin=cni \
  --pod-infra-container-image=registry.aliyuncs.com/k8sxio/pause:3.5 \
  --alsologtostderr=true \
  --logtostderr=false \
  --log-dir=/var/log/kubernetes \
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target


--bootstrap-kubeconfig  使用我们生成的凭证和kube-apiserver 通讯,只用来签发证书的权限
--cert-dir=/opt/kubernetes/k8s/ssl   自动签发证书位置
--kubeconfig 自动生成的的kubelet的配置文件,使用新生成的证书签发的凭证和kube-apiserver 通讯

红色标注的两行是加载 containerd 容器运行时,而不是docker

黄色那行,如果是docker的话,需要存在,如果是 containerd 可以不加。

通过 systemctl --now enable kubelet.service 启动

然后 修改 /opt/kubernetes/kubelet.json  启动参数 

 "address": "192.168.1.160", 为各自节点本地ip,copy到其他几个节点上,并启动。


备注:自动生成的kubelet 配置文件,参看权限的时候,其实很少权限。


查看kubelet.kubeconfig 文件权限:

kubectl --kubeconfig=/etc/kubernetes/kubelet.kubeconfig auth can-i --list -n kube-system  可以看到显示非常少的选项

但使用 kubectl --kubeconfig=/etc/kubernetes/kubelet.kubeconfig get pod -n kube-system  可以查看pod信息

why????????/

这里使用的是 node 节点授权

使用 Node 鉴权

节点鉴权是一种特殊用途的鉴权模式,专门对 kubelet 发出的 API 请求进行鉴权【只用来对kubelet 进行鉴权】

为了获得节点鉴权器的授权,kubelet 必须使用一个凭证以表示它在 system:nodes 组中,用户名为 system:node:<nodeName>。 上述的组名和用户名格式要与 kubelet TLS 启动引导过程中为每个 kubelet 创建的标识相匹配。

要启用节点授权器,请使用 --authorization-mode = Node 启动 apiserver。

要限制 kubelet 具有写入权限的 API 对象,请使用 --enable-admission-plugins=...,NodeRestriction,... 启动 apiserver,从而启用 NodeRestriction 准入插件。

要想使用node 鉴权,nodeName 必选严格符合  :

1,kubelet 具有 system:nodes 组的凭证,

2,nodeName必须为 system:node:... 格式的用户名,否则不会使用节点鉴权模式的。


备注,如果kubelet生成的kubelet-bootstrap.kubeconfig 文件中的token和kube-apiserve 中的不一直,则报如下错误:

Jul 19 13:08:56 k8s-jundax-dev-worker-01 kubelet[41863]: I0719 13:08:56.380042   41863 bootstrap.go:295] Failed to connect to apiserver: the server has asked for the client to provide credentials

Jul 19 13:08:58 k8s-jundax-dev-worker-01 kubelet[41863]: I0719 13:08:58.698566   41863 bootstrap.go:295] Failed to connect to apiserver: the server has asked for the client to provide credentials

Jul 19 13:09:00 k8s-jundax-dev-worker-01 kubelet[41863]: I0719 13:09:00.901167   41863 bootstrap.go:295] Failed to connect to apiserver: the server has asked for the client to provide credentials

十:部署kube-proxy 

默认k8s 系统内置了一个clusterrolebinding   【 system:node-proxier】 ,绑定了默认的角色:system:node-proxier,  然后把系统用户:system:kube-proxy 给了它

所有我们在建证书的时候只要CN 名称为:system:kube-proxy 即可


10.1 生成kube-proxy 证书请求【kube-proxy-csr.json】文件


{
  "CN": "system:kube-proxy",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Guangdong",
      "L": "Dongguan",
      "O": "k8s",
      "OU": "system"
    }
  ]
}

10.2 生成证书


cfssl gencert -ca=k8s-ca.pem -ca-key=k8s-ca-key.pem -config=k8s-config-csr.json -profile=k8s kube-proxy-csr.json | cfssljson -bare kube-proxy


10.3 创建system:kube-proxy 用户凭证

[root@master1 work]# kubectl config set-cluster kubernetes --certificate-authority=k8s-ca.pem --embed-certs=true --server=k8s-cluster-apiserver-lbs --kubeconfig=kube-proxy.kubeconfig

[root@master1 work]# kubectl config set-credentials kube-proxy --client-certificate=kube-proxy.pem --client-key=kube-proxy-key.pem --embed-certs=true --kubeconfig=kube-proxy.kubeconfig

[root@master1 work]# kubectl config set-context default --cluster=kubernetes --user=kube-proxy --kubeconfig=kube-proxy.kubeconfig

[root@master1 work]# kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

10.4 创建kube-proxy.json 启动参数文件,官方推荐使用json和yaml方式

{
  "apiVersion": "kubeproxy.config.k8s.io/v1alpha1",
  "bindAddress": "192.168.1.163",
  "clientConnection": {
    "kubeconfig": "/etc/kubernetes/kube-proxy.kubeconfig"
  },
  "clusterCIDR": "10.88.20.0/16",
  "healthzBindAddress": "192.168.1.163:10256",
  "kind": "KubeProxyConfiguration",
  "metricsBindAddress": "192.168.1.163:10249",
  "mode": "ipvs"
}

10.5 创建服务启动文件

首先创建kube-proxy运行目录和日志文件保存目录

mkdir -p /var/lib/kube-proxy

cat /usr/lib/systemd/system/kube-proxy.service


[Unit]

Description=Kubernetes Kube-Proxy Server

Documentation=https://github.com/kubernetes/kubernetes

After=network.target

[Service]

WorkingDirectory=/var/lib/kube-proxy

ExecStart=/usr/bin/kube-proxy \

  --config=/opt/kubernetes/kube-proxy.json \

  --alsologtostderr=true \

  --logtostderr=false \

  --log-dir=/var/log/kubernetes \

  --v=2

Restart=on-failure

RestartSec=5

LimitNOFILE=65536

[Install]

WantedBy=multi-user.target

systemctl --now enable kube-proxy.service      然后把 /usr/lib/systemd/system/kube-proxy.service 文件 /etc/kubernetes/kube-proxy.kubeconfig 文件和 /opt/kubernetes/kube-proxy.json 文件copy到 另外两个节点上,并更改 /opt/kubernetes/kube-proxy 文件的

healthzBindAddress  metricsBindAddress  为本地ip地址


十一:安装calico 网络组件

 
安装网络插件是本次折腾时间最长的一个组件。主要是卡在calico cni一直在初始化下载不下来文件。

Calico主要由三个部分组成:
Felix:以DaemonSet方式部署,运行在每一个Node节点上,主要负责维护宿主机上路由规则以及ACL规则。
BGP Client(BIRD):主要负责把 Felix 写入 Kernel 的路由信息分发到集群 Calico 网络。
Etcd:分布式键值存储,保存Calico的策略和网络配置状态。
calicoctl:允许您从简单的命令行界面实现高级策略和网络。

calico 的 Datastore 主要有两种,一种是k8s 的接口方式,第二个是etcd方式,这里使用第二种。

需要去下载一个etcd配置格式的yaml文件,下载地址为:

curl https://docs.projectcalico.org/manifests/calico-etcd.yaml -O

要启用 etcd连接证书,使用下面方法:
  1. Within the ConfigMap section, uncomment the etcd_ca, etcd_key, and etcd_cert lines so that they look as follows.

    etcd_ca: "/calico-secrets/etcd-ca"
    etcd_cert: "/calico-secrets/etcd-cert"
    etcd_key: "/calico-secrets/etcd-key"           #这里指的是container中挂在的地址。取消注释即可
    
  2. Ensure that you have three files, one containing the etcd_ca value, another containing the etcd_key value, and a third containing the etcd_cert value.

  3. Using a command like the following to strip the newlines from the files and base64-encode their contents.

    $ cat <file> | base64 -w 0
    
  4. In the Secret named calico-etcd-secrets, uncomment etcd_ca, etcd_key, and etcd_cert and paste in the appropriate base64-encoded values.

    5,etcd根证书填写根证书base64后的k8s-ca.pem  ,etcd服务证书填写etcd-server-peer.pem


    除了证书外,需要修改的还有如下:

    1,calico-etcd.yaml 文件中290行附近【calico 获取etcd 信息时候,默认连接为443端口】

     env:

    290             - name: KUBERNETES_SERVICE_HOST

    291               value: "k8s-cluster-apiserver-lbs"

    292             - name: KUBERNETES_SERVICE_PORT

    293               value: "6443"

    294             - name: KUBERNETES_SERVICE_PORT_HTTPS

    295               value:

    2, 366行附近的

    - name: CALICO_IPV4POOL_CIDR

    367               value: "10.88.20.0/16"


    yaml文件太长,这里提供下载文件

    calico-etcd.yaml 文件下载地址

    直接 kubectl apply -f calico-etcd.yaml  稍等片刻,查看pod启动情况,如果出错,通过 kubectl describe /logs  pod  -n kube-system 查看原因

    碰到的坑是:天翼云同一个去内部地址默认端口也是不通的,需要再组策略开放端,calico是需要打开tcp/179端口


    十二:安装coredns 插件

    通过 https://github.com/coredns/coredns.git clone最新coredns代码

    cd coredns/kubernetes

    #CLUSTE_DNS_IP=10.88.0.10

    #./deploy.sh -i $CLUSTER_DNS_IP>coresdns.yaml

    其中CLUSTE_DNS_IP=10.88.0.10 要与kubelet.json 中的配置文件

    "clusterDNS": [
        "10.88.0.10"
      ]
    保持一致

    coresdns.yaml 下载

    主机点不允许调度:kubectl label node k8s-jundax-dev-master-03 node-role.kubernetes.io/master=


    后记

    最近又使用kubernetes v1.20.9 在ubuntu 20.0.4 上安装了下,当然也一样遇到问题,下面是问题总结

    1,kube-controller-manager 新增参数后面忘记加 “ \ ” 导致这条参数后的参数都忽略 ,证书通讯导致问题

    2,因为copy之前安装的证书,把k8s 的ca证书混用了,导致提示【更证书】序列号不一直

    3,ubuntu 20.0.4 电信版本的os镜像使用了resolve 查询缓存,resovler监听127.0.0.1 的53端口,导致了安装coredns 出错,提示coredns检查到了无线循环。原因是coredns 默认把 /etc/resolv.conf 作为 cores的upstream,但使用了resove缓存后,/etc/resolv.conf 文件直接使用127.0.0.1 作为dns查询,如果coredns 使用这个文件,coredns不会把请求转发出去,会当成本地,这样导致环路。解决方法:在--config 加载的json 或yaml文件中,使用resolv.conf 的实际文件路径,ubuntu中的路径为  /run/systemd/resolve/resolv.conf,所以让kubelet 加载这个实际配置文件即可,配置如下: "resolvConf": "/run/systemd/resolve/resolv.conf"4,calico使用了bgp网络,导致host 主机ping pod地址不同,pod在不通主机间也不通,这个问题最后也没有解决,直接使用清空etcd 数据,重新加载群集方式解决的,问题产生应该是,我把service-rang-ip 设置成了 10.88.0.0/16, 而 cidr【pod 地址】设置成了 172.16.0.0/16 ,并且calico-etcd.yaml 配置文件中,ip_pool也指定的是172.16.0.0/16,结果导致 10.88.0.0/16 根本不受calico 管控,其实帮助文件也说的很清楚,想使用

    4,service-cluster-ip-range 选项,必循打开allocate-node-cidrs,这说明service-cluster-ip-range 是有node-cidrs分配的块【block】中分配的。

    注:calico一旦启动pod分配ip时候,再通过 kubectl apply -f calico-etcd.yaml 会报错。

    5,很多公共的镜像,国内服务器下载不是很慢就是根本下载不了,所有,以后肯定要积累一个pub仓库,方面安装下载,我使用hub.jundax.com/pub 已经建立了一个。

    6,最新k8s v1.20.x 二进制安装的,环境初始化和证书自动生成脚本下载


    使用最新组件,通过二进制方式安装kubernetes-v1.20.8(二)


    有时候通过 systemctl status kube-scheduler -l --no-pager 会发现,如下的报错:

    attachments-2022-02-Vs5X6MWO61fa8d3f342d1,png

    ,这需要在 kube-scheduler 启动文件中加入如下配置:

    [Unit]

    Description=Kubernetes Scheduler

    Documentation=https://github.com/kubernetes/kubernetes


    [Service]

    ExecStart=/usr/bin/kube-scheduler \

    --address=127.0.0.1 \

    --kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \

    --authentication-kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \

    --authorization-kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \

    --leader-elect=true \

    --alsologtostderr=true \

    --logtostderr=false \

    --log-dir=/var/log/kubernetes \

    --v=1

    Restart=on-failure

    RestartSec=5


    [Install]

    WantedBy=multi-user.target




  kube-apiserver 服务端证书请求文件【k8s-kube-apiserver-csr.json】如下:
  • 发表于 2021-07-14 18:04
  • 阅读 ( 272 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
石天
石天

437 篇文章

作家榜 »

  1. shitian 662 文章
  2. 石天 437 文章
  3. 每天惠23 33 文章
  4. 小A 29 文章