美文网首页
kube-apiserver快速复制

kube-apiserver快速复制

作者: Teddy_b | 来源:发表于2023-05-28 17:44 被阅读0次

[TOC]

背景

测试环境中,kube-apiserver为单点部署,测试时希望改为多个kube-apiserver,并通过域名访问,下面看看如果从一个kube-apiserver快速复制出另一个kube-apiserver

准备

假设你已经有了一个kube-apiserver,它是通过二进制方式部署的,并且启用的是https访问,快速复制另一个kube-apiserver的唯一难点主要在于证书如何生成,我们从kube-apiserver的启动配置开始

开始

Systemd启动配置

一般情况下,通过二进制方式部署的kube-apiserver都是通过systemd启动的,他的启动配置一般如下:

root@bigo:~# cat /lib/systemd/system/kube-apiserver.service 
[Unit]
Description=Kubernetes API Server
Documentation=https://kubernetes.io/docs/concepts/overview/components/#kube-apiserver https://kubernetes.io/docs/reference/generated/kube-apiserver/
After=network.target
# 由于没有新部署etcd,直接指向原来的etcd,所以把这个条件去掉了
After=etcd.service

[Service]
EnvironmentFile=-/etc/kubernetes/apiserver
ExecStart=/usr/bin/kube-apiserver \
            $KUBE_API_ARGS \
            $KUBE_LOGTOSTDERR \
            $KUBE_LOG_LEVEL \
            $KUBE_ETCD_SERVERS \
            $KUBE_API_ADDRESS \
            $KUBE_API_PORT \
            $KUBELET_PORT \
            $KUBE_ALLOW_PRIV \
            $KUBE_SERVICE_ADDRESSES \
            $KUBE_ADMISSION_CONTROL 
Restart=on-failure
Type=notify
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

由于我新复制出来的kube-apiserver是不需要新部署etcd的,直接指向原来的etcd,因此这个文件文件我稍微修改了下,去掉了After=etcd.service这一条件

启动环境变量

在上述启动配置中,引用了kube-apiserver的启动环境变量文件,指向的是/etc/kubernetes/apiserver,因此这个文件也需要复制到新节点上去

root@bigo:~# cat /etc/kubernetes/apiserver
KUBE_API_ADDRESS="--advertise-address=1.1.1.1 --bind-address=0.0.0.0 "  
KUBE_API_PORT="--secure-port=6443"
KUBE_ETCD_SERVERS="--etcd-servers=https://1.1.1.1:2379"
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"
KUBE_ADMISSION_CONTROL="--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,Priority,ResourceQuota" 
KUBE_API_ARGS="--allow-privileged=true \
               --feature-gates=CSIServiceAccountToken=true \
               --anonymous-auth=false \
               --alsologtostderr \
               --apiserver-count=3 \
               --audit-log-maxage=30 \
               --audit-log-maxbackup=3 \
               --audit-log-maxsize=100 \
               --audit-log-path=/var/log/kube-audit/audit.log \
               --audit-policy-file=/etc/kubernetes/audit-policy.yaml \
               --authorization-mode=Node,RBAC \
               --client-ca-file=/etc/kubernetes/ssl/k8s-root-ca.pem \
               --enable-bootstrap-token-auth \
               --enable-garbage-collector \
               --enable-logs-handler \
               --endpoint-reconciler-type=lease \
               --etcd-cafile=/etc/etcd/ssl/etcd-ca.pem \
               --etcd-certfile=/etc/etcd/ssl/etcd.pem \
               --etcd-keyfile=/etc/etcd/ssl/etcd-key.pem \
               --event-ttl=168h0m0s \
               --kubelet-https=true \
               --kubelet-certificate-authority=/etc/kubernetes/ssl/k8s-root-ca.pem \
               --kubelet-client-certificate=/etc/kubernetes/ssl/kubelet-api-admin.pem \
               --kubelet-client-key=/etc/kubernetes/ssl/kubelet-api-admin-key.pem \
               --kubelet-timeout=3s \
               --runtime-config=api/all=true \
               --service-node-port-range=30000-50000 \
               --service-account-key-file=/etc/kubernetes/ssl/k8s-root-ca.pem \
               --tls-cert-file=/etc/kubernetes/ssl/kube-apiserver.pem \
               --tls-private-key-file=/etc/kubernetes/ssl/kube-apiserver-key.pem \
               --logtostderr=false \
               --log-dir=/data/logs/kubernetes/ \
               --min-request-timeout=1800 \
               --enable-aggregator-routing=true \
               --requestheader-client-ca-file=/etc/kubernetes/ssl/front-proxy-ca.pem \
               --requestheader-allowed-names='' \
               --requestheader-extra-headers-prefix=X-Remote-Extra- \
               --requestheader-group-headers=X-Remote-Group \
               --requestheader-username-headers=X-Remote-User \
               --proxy-client-cert-file=/etc/kubernetes/ssl/front-proxy-client.pem \
               --proxy-client-key-file=/etc/kubernetes/ssl/front-proxy-client-key.pem \
               --service-account-issuer=https://1.1.1.1 \
               --service-account-signing-key-file=/etc/kubernetes/ssl/k8s-root-ca-key.pem \
               --v=10"

这个环境变量文件中,存在节点IP相关的信息,除了etcd的地址不需要修改外,其它的IP地址我们应该都改为新节点的IP地址

启动证书

在上述环境变量中,可以看到引用了很多证书文件,这些证书文件我们需要为新节点重新生成,我们将其分为一下几类:

ETCD启动证书

新节点的kube-apiserver也需要访问etcd,因此需要为其生成etcd相关的证书,主要对应的是启动参数:

--etcd-cafile=/etc/etcd/ssl/etcd-ca.pem \    # etcd的根证书
 --etcd-certfile=/etc/etcd/ssl/etcd.pem \      # 通过etcd根证书签出来的包括新节点IP的新证书
 --etcd-keyfile=/etc/etcd/ssl/etcd-key.pem \    # 通过etcd根证书签出来的包括新节点IP的新证书私钥
  • etcd-ca.pem:这个对应的是etcd的根证书,这个在所有kube-apiserver节点上是共享的,因此我们只需要把原来的etcd根证书复制到新结点上即可

  • etcd.pem和etcd-key.pem:这个对应的是访问etcd的客户端证书和私钥,由于证书需要包含新节点的IP信息,因此需要重新生成,我们使用cfssl工具来生成新证书

# 1. 准备etcd证书请求文件,必须包含我们的新节点
root@bigo:# cat etcd-csr.json 
{ 
   "CN":"etcd",
   "hosts":[ 
      "127.0.0.1",
      "1.1.1.1",
      "2.2.2.2"   #这是我们的新节点
   ],
   "key":{ 
      "algo":"rsa",
      "size":2048
   },
   "names":[ 
      { 
         "C":"CN",
         "ST":"Guangzhou",
         "L":"Guangzhou",
         "O":"k8s",
         "OU":"System"
      }
   ]
}

# 2. 生成证书;
# 其中etcd-ca.pem、etcd-ca-key.pem、etcd-ca-config.json都是原节点上的etcd证书、私钥和配置文件;
# etcd-csr.json是我们新创建的证书请求文件
root@bigo:# cfssl gencert -ca=etcd-ca.pem -ca-key=etcd-ca-key.pem -config=etcd-ca-config.json -profile=kubernetes etcd-csr.json | cfssljson -bare etcd

# 3. 查看证书;上一步后会生成etcd.pem、etcd-key.pem这个证书对,这就是新节点上用于访问etcd的证书了
root@bigo:# ls -la
total 115560
-rw-r--r-- 1 1000 1000       270 5月  24 20:15 etcd-ca-csr.json
-rw-r--r-- 1 1000 1000      1679 5月  24 20:14 etcd-ca-key.pem
-rw-r--r-- 1 1000 1000      1375 5月  24 20:12 etcd-ca.pem
-rw-r--r-- 1 1000 1000       362 5月  24 20:18 etcd-csr.json
-rw------- 1 1000 1000      1679 5月  24 20:18 etcd-key.pem
-rw-rw-r-- 1 1000 1000      1460 5月  24 20:18 etcd.pem
kube-apiserver启动证书

新结点上的kube-apiserver也需要使用https方式对外提供服务,对应启动配置里的:

--client-ca-file=/etc/kubernetes/ssl/k8s-root-ca.pem \
--tls-cert-file=/etc/kubernetes/ssl/kube-apiserver.pem \
--tls-private-key-file=/etc/kubernetes/ssl/kube-apiserver-key.pem \
  • k8s-root-ca.pem:k8s组件使用的根证书,在所有节点间也是共享的,可以直接复制到新节点上

  • kube-apiserver.pem和kube-apiserver-key.pem:新节点kube-apiserver对外提供https服务的证书对,需要重新生成,生成方式相同

# 1. 准备kube-apiserver证书请求文件,必须包含我们的新节点
root@bigo:# cat kube-apiserver-csr.json
{
    "CN": "kubernetes",
    "hosts": [
    "127.0.0.1",
    "localhost",
    "10.254.0.1",
    "1.1.1.1",
    "2.2.2.2",    #这是我们的新节点IP
        "*.master.kubernetes.node",
        "kubernetes",
        "kubernetes.default",
        "kubernetes.default.svc",
        "kubernetes.default.svc.cluster",
        "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "BeiJing",
            "L": "BeiJing",
            "O": "kubernetes",
            "OU": "System"
        }
    ]
}

# 2. 生成证书;
# 其中k8s-root-ca.pem、k8s-root-ca-key.pem、k8s-gencert.json都是原节点上的k8s证书、私钥和配置文件;
# kube-apiserver-csr.json是我们新创建的证书请求文件
root@bigo:# cfssl gencert -ca=k8s-root-ca.pem -ca-key=k8s-root-ca-key.pem -config=k8s-gencert.json -profile=kubernetes kube-apiserver-csr.json | cfssljson -bare kube-apiserver

# 3. 查看证书;上一步后会生成kube-apiserver.pem、kube-apiserver-key.pem这个证书对,这就是新节点上用于https服务的证书了
root@bigo:# ls -la
total 115560
-rw-r--r-- 1 1000 1000       386 5月  25 09:52 k8s-gencert.json
-rw------- 1 1000 1000      3243 5月  25 09:52 k8s-root-ca-key.pem
-rw-r--r-- 1 1000 1000      2069 5月  25 09:51 k8s-root-ca.pem
-rw-rw-r-- 1 1000 1000       729 5月  25 09:55 kube-apiserver-csr.json
-rw------- 1 1000 1000      1675 5月  25 09:57 kube-apiserver-key.pem
-rw-rw-r-- 1 1000 1000      2147 5月  25 09:57 kube-apiserver.pem
其它启动证书

其它的启动证书,如聚合apiserver的证书、kubelet的证书,由于证书请求文件里没有指定具体的IP,因此可以直接复制到新节点上使用,对应的启动配置:

--kubelet-certificate-authority=/etc/kubernetes/ssl/k8s-root-ca.pem \
--kubelet-client-certificate=/etc/kubernetes/ssl/kubelet-api-admin.pem \
--kubelet-client-key=/etc/kubernetes/ssl/kubelet-api-admin-key.pem \
--requestheader-client-ca-file=/etc/kubernetes/ssl/front-proxy-ca.pem \
 --proxy-client-cert-file=/etc/kubernetes/ssl/front-proxy-client.pem \
--proxy-client-key-file=/etc/kubernetes/ssl/front-proxy-client-key.pem \

他们在原节点上的证书请求文件,没有指定IP信息,可以直接复用:

root@bigo:# cat front-proxy-client-csr.json
{
  "CN": "front-proxy-client",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  }
}

root@bigo:# cat kubelet-api-admin-csr.json
{
    "CN": "system:kubelet-api-admin",
    "hosts": [],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "BeiJing",
            "L": "BeiJing",
            "O": "system:kubelet-api-admin",
            "OU": "System"
        }
    ]
}

完成

上述证书配置完成后,直接将kube-apiserver的二进制文件复制到新节点上,然后通过systemctl启动即可

扩展

  • 新节点上的kube-apiserver部署完成后,怎么验证新节点上的kube-apiserver呢?
  • 仍然是为自己生成一个新的证书即可
# 1. 准备iam证书请求文件,必须包含我们的新节点
root@bigo:# cat my-csr.json 
{
    "CN": "iam",
    "hosts": [],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "BeiJing",
            "L": "BeiJing",
            "O": "iam",
            "OU": "System"
        }
    ]
}

# 2. 生成证书;
# 其中k8s-root-ca.pem、k8s-root-ca-key.pem、k8s-gencert.json都是原节点上的k8s证书、私钥和配置文件;
#my-csr.json是我们新创建的证书请求文件
root@bigo:# cfssl gencert -ca=k8s-root-ca.pem -ca-key=k8s-root-ca-key.pem -config=k8s-gencert.json -profile=kubernetes my-csr.json | cfssljson -bare my

# 3. 使用新证书访问测试
curl -k --cert my.pem --key my-key.pem https://2.2.2.2:6443/api/v1/nodes

相关文章

网友评论

      本文标题:kube-apiserver快速复制

      本文链接:https://www.haomeiwen.com/subject/fqededtx.html