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 部署(可选)
# 随便找一台已经安装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,使用令牌登录。
修改配置,让 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 了
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于