配置高可用K8S集群

前言

Kubernetes作为容器编排管理系统,通过Scheduler、Replication Controller等组件实现了应用层的高可用,通过service实现了pod的故障透明和负载均衡。但是针对Kubernetes集群,还需要实现各个组件和服务的高可用。下面主要介绍一下搭建高可用k8s集群的步骤和配置(以下步骤是使用非容器方式启动k8s的组件和服务)。

配置步骤

1、k8s各个组件和服务的进程高可用配置在Linux系统中,我们通过Supervisor、Systemd等工具实现对服务的监控保证服务的高可用,我们的domeOS手工配置脚本中是使用Systemd的方式来启动和控制k8s的各个组件和服务的。比如kube-apiserver的服务配置:

  1. echo "[Unit]
  2. Description=kube-apiserver
  3. [Service]
  4. EnvironmentFile=/etc/sysconfig/kube-apiserver
  5. ExecStart=$K8S_INSTALL_PATH/current/kube-apiserver $ETCD_SERVERS \\
  6. $SERVICE_CLUSTER_IP_RANGE \\
  7. $INSECURE_BIND_ADDRESS \\
  8. $INSECURE_PORT \\
  9. $KUBE_APISERVER_OPTS
  10. Restart=always
  11. " > /lib/systemd/system/kube-apiserver.service

2、etcd的高可用配置由于k8s是使用etcd来存储各项配置和数据的,为了确保etcd的高可用,同时防止这些数据的丢失,我们需要使用start_etcd.sh脚本在两个及以上的node上分别启动一个etcd。

3、master的高可用配置由于master里面的kube-apiserver、kube-controller、kube-scheduler等是整个k8s的核心组件,一旦发生了故障将直接导致k8s的调度、服务等不可用,为了防止master的单点故障问题,我们使用start_master_centos.sh在两个及以上的node上分别启动master的各个组件,同时注意启动apiserver时加上apiserver-count参数(master节点数量),在controller、scheduler的启动参数里面加入—leader-elect=true参数,确保同一时间仅仅有一个controller或者scheduler生效。其中在配置apiserver的ip:port时,既可以使用本机的apiserver也可以使用下面4中所配置的虚ip:port。

4、kuber-apiserver的访问接口的负载均衡配置由于我们有多个master,自然有多个kube-apiserver,一些kubectl、client等都需要通过这个apiserver来访问k8s集群,为了确保api的高可用性并均衡api的访问压力,我们这里使用keepalived v1.2.13和haproxy v1.5.14来配置api。Keepalived的keepalived.conf配置(我们这里使用主备模式):主配置(从配置将master改为BACKUP即可):

  1. ! Configuration File for keepalived
  2. global_defs
  3. {
  4. router_id haproxy_master
  5. }
  6. vrrp_script chk_haproxy {
  7. script "/etc/keepalived/check.sh"
  8. interval 2
  9. weight 2
  10. }
  11. vrrp_instance sce_master
  12. {
  13. state MASTER
  14. interface eth0
  15. virtual_router_id 70
  16. priority 200
  17. advert_int 2
  18. smtp_alert
  19. authentication
  20. {
  21. auth_type PASS
  22. auth_pass SCEPASS
  23. }
  24. track_script {
  25. chk_haproxy
  26. }
  27. virtual_ipaddress
  28. {
  29. 192.168.64.144/22 dev eth0 scope global
  30. }
  31. }

Haproxy的haproxy.cfg配置(另外一台机器的配置与此相同):

  1. global
  2. log 127.0.0.1 local2
  3. chroot /var/lib/haproxy
  4. pidfile /var/run/haproxy.pid
  5. maxconn 4000
  6. user haproxy
  7. group haproxy
  8. daemon
  9. stats socket /var/lib/haproxy/stats
  10. defaults
  11. mode http
  12. log global
  13. option httplog
  14. option dontlognull
  15. option http-server-close
  16. option forwardfor except 127.0.0.0/8
  17. option redispatch
  18. retries 3
  19. timeout http-request 10s
  20. timeout queue 1m
  21. timeout connect 10s
  22. timeout client 1m
  23. timeout server 1m
  24. timeout http-keep-alive 10s
  25. timeout check 10s
  26. maxconn 3000
  27. stats uri /haproxy-stats
  28. frontend main 0.0.0.0:8080
  29. acl url_static path_beg -i /static /images /javascript /stylesheets
  30. acl url_static path_end -i .jpg .gif .png .css .js
  31. use_backend static if url_static
  32. default_backend app
  33. backend static
  34. balance roundrobin
  35. server static 127.0.0.1:4331 check
  36. backend app
  37. balance roundrobin
  38. server app1 192.168.65.65:8080 check
  39. server app2 192.168.65.64:8080 check
  40. server app3 192.168.65.62:8080 check

配置后的apiserver架构图

配置高可用K8S集群 - 图1

5、如果是以pod的方式启动k8s里面的一些组件或者其他服务,我们可以使用kubelet的static pod(固定pod的ip,防止漂移)。修改某个node节点上的/etc/sysconfig/kubelet配置文件,为kubelet进程配置一个manifests监视目录:KUBELET_OPTS=' —config=/etc/kubernetes/manifests,比如我想启动一个haproxy的static pod,我们只需要将haproxy对应的yaml文件放到这个目录下面即可。

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: haproxy-pod
  5. spec:
  6. hostNetwork: true
  7. containers:
  8. - name: "haproxy"
  9. image: "10.31.92.146:5000/domeos/haproxy:1.6.9"
  10. ports:
  11. - containerPort: 8083
  12. hostPort: 8083
  13. volumeMounts:
  14. - name: "configmount"
  15. mountPath: /usr/local/etc/haproxy/haproxy.cfg
  16. readOnly: true
  17. volumes:
  18. - name: "configmount"
  19. hostPath:
  20. path: "/opt/haproxy.cfg"

6、当完成k8s高可用的所有步骤后,系统的架构图如下:

配置高可用K8S集群 - 图2