kubeadm 搭建高可用集群

本贴最后更新于 1922 天前,其中的信息可能已经物是人非

kubeadm 搭建高可用集群

标签: k8s kubeadm etcd


[TOC]

1.安装环境

5 台 centos7.7 主机

  • 3 台 master
  • 1 台 haproxy(可选)
  • 1 台 node

2.准备工作

# 关闭防火墙: $ systemctl stop firewalld $ systemctl disable firewalld # 关闭selinux: $ sed -i 's/enforcing/disabled/' /etc/selinux/config $ setenforce 0 # 关闭swap: $ swapoff -a # 临时 $ vim /etc/fstab # 永久 注释掉最后一行 # 给每台机器设置主机名(可省略,方便记忆): $ hostnamectl set-hostname master1 $ hostnamectl set-hostname master2 $ hostnamectl set-hostname master3 $ hostnamectl set-hostname node $ hostnamectl set-hostname haproxy # 添加主机名与IP对应关系(可省略,方便记忆): $ cat /etc/hosts 172.18.249.67 master1 172.18.249.66 master2 172.18.249.65 master3 172.18.249.64 node 172.18.249.63 haproxy # 将桥接的IPv4流量传递到iptables的链: $ cat > /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF $ sysctl --system # 可选操作(SSH免密登录,方便后面集群证书的拷贝) # 在master1节点上执行,node节点不需要拷贝证书,可以不用设置,这个自己选择 $ ssh-keygen # 一路回车即可 $ scp .ssh/id_rsa.pub master2: $ scp .ssh/id_rsa.pub master3: $ scp .ssh/id_rsa.pub node: [root@master2 ~]# cat id_rsa.pub >> .ssh/authorized_keys [root@master3 ~]# cat id_rsa.pub >> .ssh/authorized_keys [root@node ~]# cat id_rsa.pub >> .ssh/authorized_keys

3.安装 haproxy(可选)

因为阿里云不支持 keepalived 的 vip,所以直接采用 haproxy 作为 apiserver 的控制面。

yum install -y haproxy systemctl enable haproxy # master1,2,3替换为IP,s1,2,3替换为主机名 cat << EOF >> /etc/haproxy/haproxy.cfg listen k8s-lb *:6443 mode tcp balance roundrobin server master1 172.18.249.67:6443 weight 1 maxconn 1000 check inter 2000 rise 2 fall 3 server master2 172.18.249.66:6443 weight 1 maxconn 1000 check inter 2000 rise 2 fall 3 server master3 172.18.249.65:6443 weight 1 maxconn 1000 check inter 2000 rise 2 fall 3 EOF service haproxy start

4.安装 ETCD 集群(可选)

如果想要使用外部的 etcd 集群,而不是由 k8s 自己生成 pod 在 master 节点运行,可以执行以下操作。

  • 在 3 台 master 上安装 etcd
yum install -y etcd systemctl enable etcd
  • 生成配置
    在 master1 上进行操作
etcd1=192.168.0.11 etcd2=192.168.0.12 etcd3=192.168.0.13 TOKEN=abcd1234 ETCDHOSTS=($etcd1 $etcd2 $etcd3) NAMES=("infra0" "infra1" "infra2") for i in "${!ETCDHOSTS[@]}"; do HOST=${ETCDHOSTS[$i]} NAME=${NAMES[$i]} cat << EOF > /tmp/$NAME.conf # [member] ETCD_NAME=$NAME ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="http://$HOST:2380" ETCD_LISTEN_CLIENT_URLS="http://$HOST:2379,http://127.0.0.1:2379" #[cluster] ETCD_INITIAL_ADVERTISE_PEER_URLS="http://$HOST:2380" ETCD_INITIAL_CLUSTER="${NAMES[0]}=http://${ETCDHOSTS[0]}:2380,${NAMES[1]}=http://${ETCDHOSTS[1]}:2380,${NAMES[2]}=http://${ETCDHOSTS[2]}:2380" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_INITIAL_CLUSTER_TOKEN="$TOKEN" ETCD_ADVERTISE_CLIENT_URLS="http://$HOST:2379" EOF done
  • 覆盖 etcd 配置
for i in "${!ETCDHOSTS[@]}"; do HOST=${ETCDHOSTS[$i]} NAME=${NAMES[$i]} scp /tmp/$NAME.conf $HOST: ssh $HOST "\mv -f $NAME.conf /etc/etcd/etcd.conf" rm -f /tmp/$NAME.conf done
  • 在每台节点上启动 etcd

master1 上执行 service etcd start,会一直 pending 状态,等 master2 的 etcd 启动以后就会完成。

[root@master1 ~]# service etcd start [root@master2 ~]# service etcd start [root@master3 ~]# service etcd start
  • 任意节点验证集群
etcdctl member list etcdctl cluster-health

5.安装 docker

使用阿里云 yum 源安装

$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo $ yum -y install docker-ce-18.06.1.ce-3.el7 $ systemctl enable docker && systemctl start docker $ docker --version Docker version 18.06.1-ce, build e68fc7a

此处附上一张 K8S 对应的 docker 版本,截止 2019.08.09 最新的版本支持信息:

  • Kubernetes 1.15.2 -->Docker 版本 1.13.1、17.03、17.06、17.09、18.06、18.09
  • Kubernetes 1.15.1 -->Docker 版本 1.13.1、17.03、17.06、17.09、18.06、18.09
  • Kubernetes 1.15.0 -->Docker 版本 1.13.1、17.03、17.06、17.09、18.06、18.09
  • Kubernetes 1.14.5 -->Docker 版本 1.13.1、17.03、17.06、17.09、18.06、18.09
  • Kubernetes 1.14.4 -->Docker 版本 1.13.1、17.03、17.06、17.09、18.06、18.09
  • Kubernetes 1.14.3 -->Docker 版本 1.13.1、17.03、17.06、17.09、18.06、18.09
  • Kubernetes 1.14.2 -->Docker 版本 1.13.1、17.03、17.06、17.09、18.06、18.09
  • Kubernetes 1.14.1 -->Docker 版本 1.13.1、17.03、17.06、17.09、18.06、18.09
  • Kubernetes 1.14.0 -->Docker 版本 1.13.1、17.03、17.06、17.09、18.06、18.09
  • Kubernetes 1.13.5 -->Docker 版本 1.11.1、1.12.1、1.13.1、17.03、17.06、17.09、18.06
  • Kubernetes 1.13.5 -->Docker 版本 1.11.1、1.12.1、1.13.1、17.03、17.06、17.09、18.06
  • Kubernetes 1.13.4 -->Docker 版本 1.11.1、1.12.1、1.13.1、17.03、17.06、17.09、18.06
  • Kubernetes 1.13.3 -->Docker 版本 1.11.1、1.12.1、1.13.1、17.03、17.06、17.09、18.06
  • Kubernetes 1.13.2 -->Docker 版本 1.11.1、1.12.1、1.13.1、17.03、17.06、17.09、18.06
  • Kubernetes 1.13.1 -->Docker 版本 1.11.1、1.12.1、1.13.1、17.03、17.06、17.09、18.06
  • Kubernetes 1.13.0 -->Docker 版本 1.11.1、1.12.1、1.13.1、17.03、17.06、17.09、18.06
  • Kubernetes 1.12.* -->Docker 版本 1.11.1、1.12.1、1.13.1、17.03、17.06、17.09、18.06
  • Kubernetes 1.11.* -->Docker 版本 1.11.2 到 1.13.1、17.03
  • Kubernetes 1.10.* -->Docker 版本 1.11.2 到 1.13.1、17.03

如果没有搭建类似 harbor 的私有仓库,因为镜像拉取过慢,所以此处需要配置一个镜像加速器。
您可以通过修改 daemon 配置文件/etc/docker/daemon.json 来使用加速器,加速器地址可以填写阿里云的容器镜像服务提供的,是免费使用的。

sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://*************"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker

但是 docker 默认驱动程序是 cgroupfs,而 k8s1.17 是 systemd,所以我们需要修改 docker 的默认驱动
官方文档推荐配置

cat > /etc/docker/daemon.json <<EOF { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ], "registry-mirrors": ["https://6ekruvxo.mirror.aliyuncs.com"] # 使用自己或其他可用的镜像加速器 } EOF systemctl daemon-reload && systemctl restart docker

6.安装 k8s

# 添加源 $ cat > /etc/yum.repos.d/kubernetes.repo << EOF [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF # master节点 $ yum install -y kubelet-1.17.0 kubeadm-1.17.0 kubectl-1.17.0 # node节点 $ yum install -y kubelet-1.17.0 kubeadm-1.17.0 $ systemctl enable kubelet && systemctl start kubelet #安装kubelet 后会在/etc下生成文件目录/etc/kubernetes/manifests/

7.部署 Kubernetes Master

创建 kubeadm 配置文件
官网 init 初始化配置大全

cat << EOF > kubeadm-config.yaml apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration etcd: local: dataDir: "/var/lib/etcd" networking: serviceSubnet: "10.96.0.0/16" podSubnet: "10.244.0.0/16" dnsDomain: "cluster.local" kubernetesVersion: "v1.17.0" controlPlaneEndpoint: "172.18.249.63:6443" apiServer: extraArgs: authorization-mode: "Node,RBAC" certSANs: - "172.18.249.63" timeoutForControlPlane: 4m0s imageRepository: "registry.aliyuncs.com/google_containers" EOF kubeadm init --config kubeadm-config.yaml

初始化成功后,保存 token,执行

mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config

安装 cni 网络组件
官方文档推荐

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml

然后可以进行查看 master 的状态,如果节点处于 notready,可能是因为 flannel 正在拉取镜像,需要等待一段时间

kubectl get cs kubectl get nodes

8.加入 k8s 集群

在 master1 节点上进行操作,将生成的证书拷贝到其他的 master 节点

ssh master2 mkdir -p /etc/kubernetes/pki/etcd ssh master3 mkdir -p /etc/kubernetes/pki/etcd scp /etc/kubernetes/admin.conf root@master2:/etc/kubernetes scp /etc/kubernetes/admin.conf root@master3:/etc/kubernetes scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@master2:/etc/kubernetes/pki scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@master3:/etc/kubernetes/pki scp /etc/kubernetes/pki/etcd/ca.* root@master2:/etc/kubernetes/pki/etcd scp /etc/kubernetes/pki/etcd/ca.* root@master3:/etc/kubernetes/pki/etcd

然后再 master2 和 master3 节点上分别执行 join 命令,使用自己生成保存的 token,master 节点会多一个参数==--control-plane==

kubeadm join 172.18.249.82:6443 --token 85xqaz.7wj2oonv3ulpfbix \ --discovery-token-ca-cert-hash sha256:7d334aa7e49ea4934505686c311139c07cd278e2e92faa51fa74429399519772 \ --control-plane

然后是 node 节点

kubeadm join 172.18.249.82:6443 --token 85xqaz.7wj2oonv3ulpfbix \ --discovery-token-ca-cert-hash sha256:7d334aa7e49ea4934505686c311139c07cd278e2e92faa51fa74429399519772

等几分钟之后,就可以看到节点处于 ready 状态

[root@k8s001 kubernetes]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s001 Ready master 9m22s v1.15.0 k8s002 Ready <none> 2m44s v1.15.0 k8s003 Ready <none> 2m41s v1.15.0

9. 测试 kubernetes 集群

在 Kubernetes 集群中创建一个 pod,验证是否正常运行:

$ kubectl create deployment nginx --image=nginx $ kubectl expose deployment nginx --port=80 --type=NodePort $ kubectl get pod,svc

10.rancher 部署(可选)

rancher 官网

# 随便找一台已经安装docker的机器 $ sudo docker run -d --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher

然后等到镜像启动成功之后,访问 UI 界面,输入初始化密码,然后加入已存在的集群。

11.部署 Dashboard(可选)

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml

默认镜像国内无法访问,修改 kubernetes-dashboard.yaml 修改镜像地址为:
先将文件下载下来:

wget https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml # 原image 地址 # k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1 # 修改为 # roeslys/kubernetes-dashboard-amd64:v1.10.1

默认 Dashboard 只能集群内部访问,修改 Service 为 NodePort 类型,暴露到外部:不修改的话外部不能访问。

kind: Service apiVersion: v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kube-system spec: type: NodePort ports: - port: 443 targetPort: 8443 nodePort: 30000 selector: k8s-app: kubernetes-dashboard

可以添加 nodePort 指定端口,然后访问地址,必须火狐浏览器用 https 打开:https://NodeIP:30000
后续也可以自己添加 ssl,安全方面后续再说。

$ kubectl apply -f kubernetes-dashboard.yaml $ kubectl get pods,svc -n kube-system 创建service account并绑定默认cluster-admin管理员集群角色: $ kubectl create serviceaccount dashboard-admin -n kube-system $ kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin $ kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

记录保存 token,使用令牌登录。

image

修改配置,让 dashboard 能够在谷歌等浏览器上正常运行。

火狐浏览器能够正常访问是因为它有一个不安全模式运行,而默认的 dashboard 应用的 https 是不安全的,因此只有火狐可以访问。我自己也测试过,你如果直接在 master 节点上 curl https://127.0.0.1:30000,页面数据是出不来的。但是当我们跳过安全认证这一块,curl https://127.0.0.1:30000 -k,这个时候可以看到已经正常返回了页面的 html 信息。

下面是生成证书的一些步骤,使用新的证书来启动 dashboard

cd /root mkdir key && cd key #生成证书 openssl genrsa -out dashboard.key 2048 openssl req -new -out dashboard.csr -key dashboard.key -subj '/CN=172.18.249.67'(我测试的时候填写的外网地址,都可以) openssl x509 -req -in dashboard.csr -signkey dashboard.key -out dashboard.crt #删除原有的证书secret kubectl delete secret kubernetes-dashboard-certs -n kube-system #创建新的证书secret kubectl create secret generic kubernetes-dashboard-certs --from-file=dashboard.key --from-file=dashboard.crt -n kube-system #查看pod kubectl get pod -n kube-system #重启pod kubectl delete pod <pod name> -n kube-system

完成以上操作之后我们重新刷新一下谷歌浏览器
这个时候我们就可以通过谷歌浏览器打开 kubernetes dashboard 了

  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    116 引用 • 54 回帖 • 2 关注
  • kubeadm
    2 引用
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    6 引用 • 26 回帖 • 546 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...