{
"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
}
}
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 配置 的证书功能
然后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内容如下
[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
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
{
"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"
}
]
}
生成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
设置集群参数
[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
其中--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 文件,证书文件复制到另外两个节点并启动服务。
{
"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
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
把启动参数文件,启动文件,kube-scheduler.kubeconfig 文件,证书文件复制到另外两个节点并启动服务。
证书文件和证书请求配置文件可以这里下载
下载下来的文件解压后,有四个文件 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 容器运行时,而不是docker
黄色那行,如果是docker的话,需要存在,如果是 containerd 可以不加。
通过 systemctl --now enable kubelet.service 启动
然后 修改 /opt/kubernetes/kubelet.json 启动参数
备注:自动生成的kubelet 配置文件,参看权限的时候,其实很少权限。
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 节点授权
节点鉴权是一种特殊用途的鉴权模式,专门对 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
所有我们在建证书的时候只要CN 名称为:system:kube-proxy 即可
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
[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
[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 文件的
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
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中挂在的地址。取消注释即可
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.
Using a command like the following to strip the newlines from the files and base64-encode their contents.
$ cat <file> | base64 -w 0
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 查看原因
十二:安装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 中的配置文件
后记:
最近又使用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 会发现,如下的报错:
,这需要在 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
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!