建议切换至 root 用户进行操作,系统最好是全新安装

配置内核模块( kube-proxy ipvs 模式需要使⽤),内核参数,并关闭 swap

$ cat >> /etc/modules <<EOF
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack_ipv4
br_netfilter
EOF
$ cat > /etc/sysctl.d/k8s.conf <<EOF
net.ipv4.ip_forward = 1
vm.swappiness = 0
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
$ swapoff -a
$ sed -i 's/.*swap.*/#&/' /etc/fstab

安装 Docker

不能直接使用脚本安装 docker,默认会安装最新的版本,k8s 不能支持,这里采用 docker-ce 18.06.3~ce~3-0~ubuntu

$ vim /etc/apt/sources.list.d/docker.list
# 添加阿里云的源
deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial stable
  • 安装指定版本的 docker
$ apt-get update
$ apt-get install docker-ce=18.06.3~ce~3-0~ubuntu
  • 配置 docker
$ vim /etc/docker/daemon.json
# 粘贴以下配置
{
 "registry-mirrors": ["https://n6syp70m.mirror.aliyuncs.com"],
 "iptables": false,
 "ip-masq": false,
 "storage-driver": "overlay2",
 "exec-opts": ["native.cgroupdriver=systemd"],
 "log-driver": "json-file",
 "log-opts": { "max-size": "20m" }
}

安装 kubectl,kubeadm,kubelet,ipvsadm,ipset

  • 添加阿里云 k8s 源
$ curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
$ cat > /etc/apt/sources.list.d/k8s.list <<EOF
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
  • 更新&安装
$ apt-get update
$ apt-get install kubeadm kubectl kubelet ipvsadm ipset -y
  • 重启服务器
$ reboot

如果有其他 node 也要加入集群那么需要依次执行上面的步骤,确保 master 和 node 上的版本一致

使⽤ kubeadm 初始化集群

  • 初始化集群
$ kubeadm init --image-repository registry.aliyuncs.com/google_containers --pod-network-cidr=10.244.0.0/16 

初始化成功后会看到提示 kubeadm 如何在 worker 节点,通过 kubeadm join 命令加入集群,可以先复制下来备用。

  • 复制 kubectl 配置文件
$ mkdir -p $HOME/.kub
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
  • 验证集群
$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   10m
$ kubectl get pods -n kube-system
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-58cc8c89f4-dphr5             0/1     Pending   0          10m
coredns-58cc8c89f4-zqv8l             0/1     Pending   0          10m
etcd-k8s-master                      1/1     Running   0          9m58s
kube-apiserver-k8s-master            1/1     Running   0          10m
kube-controller-manager-k8s-master   1/1     Running   0          10m
kube-proxy-77k4s                     1/1     Running   0          10m
kube-proxy-mnzss                     1/1     Running   0          7m41s
kube-scheduler-k8s-master            1/1     Running   0          9m49s

可以发现 coredns 还处于 pending 状态,这是由于⽹络插件还未安装。

安装⽹络插件 flannel

由于 flannel 使⽤的镜像默认托管在 quay.io 上,国内访问速度会特别慢,所以可以先通过其他渠道将镜像拉取到本地,避免后续部署失败。在从 mirror 拉取镜像时,需要先看下 github 上 flannel.yaml ⽂件中指定的镜像版本是什么,比如本⽂档编写时使⽤的是 quay.io/coreos/flannel:v0.11.0-amd64,所以可以先通过以下命令拉取镜像

$ docker pull quay-mirror.qiniu.com/coreos/flannel:v0.11.0-amd64
$ docker tag quay-mirror.qiniu.com/coreos/flannel:v0.11.0-amd64 quay.io/coreos/flannel:v0.11.0-amd64
  • 部署 flannel
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

此时再次通过 kubectl get pods -n kube-system 可以看到 coredns 已经变为
running 状态。

移除 master 节点的 traint,允许 master 节点运⾏其他 pod

注意下⾯命令中的 k8s-master 需要修改为本地相应的 master node 的名称,可以用 kubectl get nodes 查看

$ kubectl taint nodes k8s-master node-role.kubernetes.io/master- 

添加 node

在 node 上安装好了工具后,输入初始化完成后提示的命令加入集群

$ kubeadm join 172.16.78.99:6443 --token it9cx7.0xzqbse2yd2e3tkf --discovery-token-ca-cert-hash sha256:976383da05621eab96c2b792319684938a85223202234742bf327730fa14ec78

发布 Nginx 验证集群

$ kubectl create deployment nginx --image=nginx
$ kubectl expose deploy nginx --type=NodePort --port=8080 --target-port=80 --name=nginx-svc
  • 可以通过下⾯的命令查看创建的 pod, deployment, 以及 service
$ kubectl get pods 
NAME READY STATUS RESTARTS AGE
nginx-554b9c67f9-9ts2d 1/1 Running 0 111s
$ kubectl get deploy 
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 69s
$ kubectl get svc 
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 28m
nginx-svc NodePort 10.102.28.219 <none> 8080:31469/TCP 62s

可以看到 nginx 暴露在 31469 端口,因为此时是单节点,所以可以直接使用 节点IP:31469 访问到 nginx

部署 Dashboard

这里采用修改 yaml 文件的方式部署,首先从 github 上拉取 kubernetes-dashboard.yaml

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

将其中的 images 修改为 lizhenliang/kubernetes-dashboard-amd64:v1.10.1,默认 Dashboard 只能集群内部访问,修改 Service 为 NodePort 类型,暴露到外部 30001 端口:

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: 30001
  selector:
    k8s-app: kubernetes-dashboard
$ kubectl apply -f kubernetes-dashboard.yaml
  • 访问面板,注意这里必须是 https,提示不安全直接忽略
$ https://ip:30001
  • 创建 service account 并绑定默认 cluster-admin 管理员集群角色:
$ cat <<EOF | kubectl apply -f - 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system
EOF
  • 获取 admin-user 账户的 Token
$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')

复制上⾯命令输出结果的 Token,输⼊ dashboard token 登录框就可以完成登录。

将 kube-proxy 切换到 ipvs 模式

当 K8S 集群运⾏的服务数量很多时,kube-proxy ⼯作在 ipvs 模式将获得更好的性能。默认情况下 kube-proxy 允许在 iptables 模式,但我们可以通过修改 kube-proxy ConfigMap 快速将 kube-proxy 切换到 ipvs 模式。

⾸先,通过下⾯的命令更新 kube-proxy ConfigMap

$ kubectl -n kube-system edit cm kube-proxy

修改 mode 字段值为 “ipvs”

然后通过命令 kubectl -n kube-system rollout restart ds/kube-proxy 重启 kube-proxy。当重启完成后,可以通过命令 kubectl -n kube-system logs -f -lk8s-app=kube-proxy --all-containers 验证 kube-proxy 已经允许在 ipvs 模式。

同时通过命令 ipvsadm -L 也将会发现各种转发规则已经成功添加。


且乐生前一杯酒