K8S-二进制文件部署安全高可用集群

前言:

在正式环境中,为确保Master的高可用,并启用安全访问机制,至少包括以下几个方面:

1. Master的kube-apiserver,kube-controller-mansger,kube-scheduler服务至少以三节点的多实例方式部署。

2. Master 启用基于CA认证的HTTPS安全机制。

3. etcd至少以3个节点的集群模式部署。

4. etcd集群启用基于CA认证的HTTPS安全机制。

5. Master 启用RBAC授权模式。

 

在master的3个节点之前,应通过一个负载均衡器对客户端的唯一访问入口地址,负载均衡可以选择的方案较多,本文以Haproxy搭配keepalived为例。

环境准备:

master:192.168.18.3-5

VIP: 192.168.18.100

下面分别对etcd,负载均衡器,Master,node等组件如何进行高可用部署,关键配置,CA认证配置进行详细说明。

一、创建CA根证书。

自制CA机构,etcd和k8s在制作CA证书时,均需要基于CA根证书,本文以为k8s和etcd使用同一套CA根证书为例,对CA根证书的制作进行说明。

创建CA根证书,私钥ca.key、证书文件ca.crt.

openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=192.168.18.3" -days 36500 -out ca.crt

将生成的ca.key和ca.crt保存在/etc/kubernetes/pki目录下。

二、部署安全的ETCD高可用集群

etcd作为集群的主数据库,在安装kubernetes各服务组件之前需要首先安装启动。

在GitHub官网下载etcd二进制文件,解压缩得到etcd和etcdctl文件,将他们复制到/usr/bin目录下。

 2.1 创建etcd自启动脚本

[Unit]
Description=etcd key-value store
Documentation=https://github.com/etcd-io/etcd
After=network.target

[Service]
EnvironmentFile=/etc/etcd/etcd.conf
ExecStart=/usr/bin/etcd
Restart=always [Install] WantedBy
=multi-user.target

其中,EnvironmentFile需要指定配置文件的全路径。

2.2 创建ETCD的CA证书

创建x509 v3配置文件etcd_ssl.cnf,其中subjectAltName参数(alt_names)包括所有的etcd主机的IP地址。

[ req ]
req_extensions = v3_req
distinguished_name = req_distinguished_name

[ req_distinguished_name ]

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation,digitaSignature, keyEncipherment
subjectAltName = @alt_names

[ alt_names ]
IP.1 = 192.168.18.3
IP.2 = 192.168.18.4
IP.3 = 192.168.18.5

使用openssl创建etcd的服务端CA证书,包括etcd_server.key和etcd_server.crt文件。将其保存在/etc/etcd/pki目录下。

openssl genrsa -out etcd_server.key 2048
openssl req -x509 -new -nodes -key etcd_server.key -config etcd_ssl.cnf -subj "/CN=etcd-server"  -out etcd_server.csr
openssl -x509 -req -in etcd_server.csr -CA /etc/kubernetes/pki/ca.crt -CAkey=/etc/kubernetes/pki/ca.key -CAcreateserial -days 36500 -extensions v3_req -extfile etcd_ssl.cnf   -out etcd_server.crt

 因为是双向HTTPS认证,还需要创建客户端使用的CA证书,包括etcd_clint.key和etcd_clint.crt,将其保存到/etc/etcd/pki目录下,后续供apiserver连接使用。

openssl genrsa -out etcd_clint.key 2048
openssl req -x509 -new -nodes -key etcd_clint.key -config etcd_ssl.cnf -subj "/CN=etcd-server"  -out etcd_client.csr
openssl -x509 -req -in etcd_clint.csr -CA /etc/kubernetes/pki/ca.crt -CAkey=/etc/kubernetes/pki/ca.key -CAcreateserial -days 36500 -extensions v3_req -extfile etcd_ssl.cnf   -out etcd_clint.crt

2.3 etcd参数配置说明

# 节点1配置
ETCD_NAME=etcd1     # 节点名称,唯一
ETCD_DATE_DIR =/rtc/etcd/data  # etcd数据存储目录

ETCD_CERT_FILE=/etc/etcd/pki/etcd_server.crt          
ETCD_KEY_FILE=/etc/etcd/pki/etcd_server.key           
ETCD_TRUSTED_CA_FILE=/etc/kubernetes/pki/ca.crt
ETCD_CLIENT_CERT_AUTH=/etc/true    # 开启客户端证书认证
ETCD_LISTEN_CLIENT_URLS=https://192.168.18.3:2379  # 为客户端提供的监听地址
ETCD_ADVERTISE_CLIENT_URLS=https://192.168.18.3:2379  # 其他节点监听的地址
ETCD_PEER_CERT_FILE=/etc/etcd/pki/etcd_server.crt     # 集群内各节点相互认证的证书   
ETCD_PEER_KEY_FILE=/etc/etcd/pki/etcd_server.key      # key
ETCD_PEER_TRUSTED_CA_FILE=/etc/kubernetes/pki/ca.crt  # 根证书
ETCD_LISTEN_PEER_URLS=https://192.168.18.3:2380
ETCD_INITIAL_ADVERTISE_PEER_URLS=https://192.168.18.3:2380

ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster   # 集群名称
ETCD_INITIAL_CLUSTER="etcd1=https://192.168.18.3:2380,etcd2=https://192.168.18.4:2380,etcd1=https://192.168.18.5:2380"  # 集群各节点的endpoint
ETCD_INITIAL_CLUSTER_STATE=new # 新建集群为new,存在为existing

节点二配置
.....

 主要配置参数包括为客户端和集群及其他节点配置的各监听URL地址(均为HTTPS),并配置相应的CA证书。

三、部署安全的kubernetes Master高可用集群

在Master节点需要部署的服务包含etcd,apiserver,controller-manager和scheduler。

在node节点需要部署dockers,kubelet,和kube-proxy。

将kubernetes二进制可执行文件拷贝到/usr/bin目录下,然后创建启动脚本service。

3.1 部署apiserver

设置apiserver需要的CA相关证书,准备master_ssl.cnf文件用于生成x509 v3版本的证书。

[ req ]
req_extensions = v3_req
distinguished_name = req_distinguished_name

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation,digitaSignature, keyEncipherment
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
DNS.5 = k8s-1
DNS.6 = k8s-2
DNS.7 = k8s-3
IP.1 = 169.169.0.1  # master service 虚拟服务的clusterip地址
IP.2 = 192.168.18.3
IP.3 = 192.168.18.4
IP.4 = 192.168.18.5
IP.5 = 192.168.18.100   # 负载均衡地址

3.2 创建apiserver服务端的CA证书,将其保存到/etc/kubernetes/pki目录下:

openssl genrsa -out apiserver.key 2048
openssl req -x509 -new -nodes -key apiserver.key -config master_ssl.cnf -subj "/CN=192.168.18.3"  -out apiserver.csr
openssl -x509 -req -in apiserver.csr -CA /etc/kubernetes/pki/ca.crt -CAkey=/etc/kubernetes/pki/ca.key -CAcreateserial -days 36500 -extensions v3_req -extfile etcd_ssl.cnf   -out apiserver.crt

3.3 创建apiserver客户端的CA证书,将其保存到/etc/kubernetes/pki目录下。

openssl genrsa -out apiserver_clint.key 2048
openssl req -x509 -new -nodes -key apiserver_clint.key  -subj "/CN=admin"  -out apiserver_client.csr
openssl -x509 -req -in apiserver_clint.csr -CA /etc/kubernetes/pki/ca.crt -CAkey=/etc/kubernetes/pki/ca.key -CAcreateserial -days 36500  -out apiserver_clint.crt

3.4  创建apiserver启动脚本service

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

[Service]
EnvironmentFile=/etc/kubernetes/apiserver
ExecStart=/usr/bin/kube-apiserver $KUBE_API_ARGS
Restart=always

[Install]
WantedBy=multi-user.target

3.5 /etc/kubernetes/apiserver 内容参数详解

KUBE_API_ARGS="--INSECURE-PORT=0 \  # 0表示关闭http访问
--secure-port=6443 \   # https端口
--tls_cert-file=/etc/kubernetes/pki/apiserver.crt \   # 服务端证书
--tls-private-key-file=/etc/kubernetes/pki/apiserver.key \  # 服务端私钥
--client-ca-file=/etc/kubernetes/pki/ca.crt \  # CA
--apiserver-count=3 --endpoint-reconciler-type=master-count \  # 实例数量
--etcd-server=https://192.168.18.3:2379,https://192.168.18.4:2379,https://192.168.18.5:2379 \  # 连接etcd的url列表
--etcd-cafile=/etc/kubernetes/pki/ca.crt \  # etcd使用的根证书路径
--etcd-certfile=/etc/kubernetes/pki/etcd_client.crt \  # etcd客户端CA证书文件,告诉APIServer拿着这个客户端证书去连接etcd
--etcd-keyfile=/etc/kubernetes/pki/etcd_client.key \   # etcd客户端私钥
--service-cluster-ip-range=169.169.0.0/16 \   # service虚拟IP地址范围
--service-node-port-range=30000-32767 \   # nodeport端口范围
--allow-privileged=true \   # 允许容器特权运行
--logtostderr=false --log-dir=/var/log/kubernetes --v=0" # --v日志级别,logtostderr表示不输出到stderr,可以输出到日志文件

 3.6 创建客户端连接apisever 服务所需的kubeconfig文件

为控制器,调度器,kubelet,kubectl,kube-proxy统一创建一个kubeconfig文件连接到apiserver的配置文件。

将kubeconfig文件保存在/etc/kubernetes目录下。

apiVersion: v1
kind: Config
clusters:
- name: default
  cluster:
  server: https://192.168.18.100:9443   //vip地址和端口
  certificate-authority: /etc/kubernetes/pki/ca.crt   //根证书
user:
- name: admin   //名称和签发证书的名称一致,"/CN"
  user:
    client-certificate: /etc/kubernetes/pki/client.crt   //为客户端签发的连接证书
    client-key: /etc/kubernetes/pki/client.key   //客户端私钥文件绝对路径
contexts:
- context:
    cluster: default
    user: admin
  name: default
 current-context: default

 四、部署kube-controller-manager

4.1 创建启动脚本

[Unit]
Description=kuberbetes Controller-manager
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
EnvironmentFile=/etc/kubernetes/controller-manager
ExecStart=/usr/bin/controller-manager  $KUBE_CONTROLLER_MANAGER_ARGS
Restart=always

[Install]
WantedBy=multi-user.target

4.2 配置文件 /etc/kubernetes/controller-manager 设置启动参数

KUBE_CONTROLLER_MANAGER_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig \
--leader-elect=true \   //启动选举机制
--service-cluster-ip-range=169.169.0.0/16 \  //需要和APIserver保持一致
--service-account-private-key-file=/etc/kubernetes/pki/apiserver.key \   //为serviceAccount自动颁发Token使用的私钥路径
--root-ca-file=/etc/kubernetes/pki/ca.crt \
--log-dir=/var/log/kubernetes --logtostderr=false --v=0"

五、部署kube-scheduler服务

5.1 启动脚本

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

[Service]
EnvironmentFile=/etc/kubernetes/scheduler
ExecStart=/usr/bin/kube-schduler  $KUBE_SCHDULER_ARGS
Restart=always

[Install]
WantedBy=multi-user.target

5.2 配置文件对参数说明

KUBE_SCHEDULER_ARGS="--KUBECONFIG=/etc/kubernetes/kubeconfig \   //拿着APIServer签发的客户端证书和私钥访问
--leader-elect=true \   //启动选举
--logtostderr=false --log-dir=/var/log/kubernetes --v=0"

六、使用HAProxy和keepalived部署高可用负载均衡器

6.1 在3个apiserver前面部署负载均衡器,VIP作为客户访问入口。

frontend  kube-apiserver
    mode        tcp
    bind          *:9443
    option       tcplog
    default_backend    kube-apiserver

..

backend kube-apiserver
    mode  tcp
    balance  roundrobin
    server k8s-master1 192.168.18.3:6443 check
    server k8s-master2 192.168.18.4:6443 check
    server k8s-master3 192.168.18.5:6443 check

 6.2 在三台master服务器安装keepalived

global_defs {
router_id LVS_1 //按照实际填写

vrrp_script checkhaproxy { script
"/usr/bin/check-haproxy.sh" interval 2 weight -30 } vrrp_instance VI_1 { //虚拟路由VRRP名称,名称必须一致,表示在同一个集群 state MASTER //其他为BACKUP interface ens33 //待设置VIP地址的网卡 virtual_router_id 51 //路由id priority 100 //优先级 advert_int 1 cirtual_ipaddress { 192.168.18.100/24 dev ens33 //VIP地址 } track_script { checkhaproxy //健康检查脚本 } }

 将健康检测脚本定期执行

6.3 以容器方式运行keepalived,在18.3和18.4两台机器启动keepalived,将keepalived.conf文件挂载到容器内。

docker run -d --name k8s-keepalived --restart=always --net=host --cap-add=NET_ADMIN --cap-add=NET_BROADCAST --cap-add=NET_RAW -v ${PWD}/keepalived.conf:/container/service/keepalived/assets/keepalived.conf -v ${PWD}/check-haproxy.sh:/usr/bin/check-haproxy.sh  osixia/keepalived:2.0.20 --copy-service

 七、部署Node服务

在Node节点需要部署docker,kubelet,kube-proxy,CNI网络插件,DNS插件等等。

 7.1 部署kubelet

7.1.1 启动脚本
[Unit]
Description=kuberbetes Kubelet Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
EnvironmentFile=/etc/kubernetes/kubelet
ExecStart=/usr/bin/kubelet  $KUBELET__ARGS
Restart=always

[Install]
WantedBy=multi-user.target

 

7.1.2 配置文件/etc/kubernetes/kubelet对KUBELET_ARGS说明
KUBELET_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig \  //需要复制相关客户端证书文件到node节点的/etc/kubernetes/pki目录下
--config=/etc/kubernetes/kubelet.conf \
--hostname-override=node1\ //node在集群中的名称,可以设置IP或域名
--network-plugin=cni \ //网络插件类型
--logtostderr=false --log-dir=/var/log/kubernetes --v=0
"

 

7.1.3 kubelet.config内容
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
adress: 0.0.0.0   //服务监听地址
port: 10250
cgroupDriver: cgroupfs    //可选systend
clusterDNS: ["169.168.0.100"]  //集群DNS服务地址
clusterDomain: cluster.local   //DNS后缀
authentication:  //是否允许匿名访问或者webhook进行鉴权
    anonymous:
        enabled: true

 

7.2 部署kube-proxy服务

7.2.1 启动脚本
[Unit]
Description=kuberbetes Kube-Proxy Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
EnvironmentFile=/etc/kubernetes/proxy
ExecStart=/usr/bin/kubelet  $KUBE_PROXY_ARGS
Restart=always

[Install]
WantedBy=multi-user.target
 7.2.2 /etc/kubernetes/proxy
KUBE_PROXY_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig \
--hostname=override=node2 \
--proxy-mode=iptables \   //包括ipvs
--logtostderr=false --log-dir=/var/log/kubernetes --v=0"

 

 

 

posted @ 2022-04-29 20:11  不会跳舞的胖子  阅读(266)  评论(0编辑  收藏  举报