k8s 安装与卸载

1. 安装

1.1. 安装前提

  1. 一台或多台运行以下其中一项的计算机:
    Ubuntu 16.04以上
    Debian 9+
    CentOS的7
    红帽企业Linux(RHEL)7
    Fedora 25+
    HypriotOS v1.0.1 +
    容器Linux(已通过1800.6.0测试)
  2. 每台机器2 GB或更多的RAM(更少的空间将为您的应用程序留出很少的空间)
  3. 2个或更多CPU
  4. 群集中所有计算机之间的完整网络连接(可以使用公用或专用网络)
  5. 每个节点的唯一主机名,MACqi和product_uuid。有关更多详细信息,请参见此处。
  6. 某些端口在您的计算机上打开。有关更多详细信息,请参见此处。
  7. 交换已禁用。您必须禁用交换才能使kubelet正常工作。
# 临时禁用
sudo swapoff -a

# 永久禁用
sudo sed -i "/ swap / s/^/#/" /etc/fstab
sudo swapoff -a
  1. 关闭防火墙
sudo ufw disable

1.2. 安装组件 For all nodes

集群中的所有节点需要安装 1.kubeadm ,2.kubelet , 3.kubectl 4.docker
kubeadm: 引导启动集群的 the command to bootstrap the cluster.
kubelet: 再所有节点上执行启动pod及容器的组件 the component that runs on all of the machines in your cluster and does things like starting pods and containers.
kubectl: 与集群沟通工具 the command line util to talk to your cluster.

# 国内建议更换镜像 
apt-get update && apt-get install -y apt-transport-https
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
apt-get update
# 安装 kubelet kubeadm kubectl
sudo apt-get install -y kubelet=1.15.0-00 kubeadm=1.15.0-00  kubectl=1.15.0-00 
# 标记该软件包不被自动更新
sudo apt-mark hold kubelet kubeadm kubectl
# 安装docker
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun


#--------------------
### 官方指令
sudo apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
# 安装 kubelet kubeadm kubectl
sudo apt-get install -y kubelet kubeadm kubectl  
# 标记该软件包不被自动更新
sudo apt-mark hold kubelet kubeadm kubectl
systemctl enable kubelet

1.3. 初始化集群控制平台节点 master

# 官方指令
kubeadm init

#-------推荐方案
# 先使用国内镜像先pull images 
kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers
# 初始化(flannel 插件)
kubeadm init --pod-network-cidr=10.244.0.0/16 --image-repository=registry.aliyuncs.com/google_containers --apiserver-bind-port=6443

初始化之后会显示如下内容:

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

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

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 172.24.195.42:6443 --token bdibtv.8iu07mfcpssfdrmg \
    --discovery-token-ca-cert-hash sha256:6732957bd86580ac23b70bb7a1a0135149db580e3f25a7ce24c4c1409cd5b923

如果期望以常规用户(运行,执行以下命令 :

#root用户也要
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

if you are the root user, you can run:

export KUBECONFIG=/etc/kubernetes/admin.conf

使用kubeadm init设置集群时,要记住几点,并且在Kubernetes站点kubeadm cluster create上有明确记录:

  1. 如果您已经创建了先前的集群,则 kubeadm reset
  2. 从主目录或根目录中删除.kube文件夹(也可以使用systemctl停止kubelet,以实现平稳设置)
  3. 永久禁用计算机上的交换swap,尤其是在重新引导Linux系统时
  4. 别忘了,根据网站上(不是Kubernetes网站)上提供的说明安装 a pod network add-on 插件。
  5. 遵循kubeadm在命令窗口上给出的后期初始化步骤。
docker images

>>>
registry.aliyuncs.com/google_containers/kube-proxy                v1.17.0             7d54289267dc        10 days ago         116MB
registry.aliyuncs.com/google_containers/kube-scheduler            v1.17.0             78c190f736b1        10 days ago         94.4MB
registry.aliyuncs.com/google_containers/kube-apiserver            v1.17.0             0cae8d5cc64c        10 days ago         171MB
registry.aliyuncs.com/google_containers/kube-controller-manager   v1.17.0             5eb3b7486872        10 days ago         161MB
registry.aliyuncs.com/google_containers/coredns                   1.6.5               70f311871ae1        6 weeks ago         41.6MB
registry.aliyuncs.com/google_containers/etcd                      3.4.3-0             303ce5db0e90        7 weeks ago         288MB
registry.aliyuncs.com/google_containers/pause                     3.1                 da86e6ba6ca1        24 months ago       742kB

另外,请不要忘记执行以下命令以在创建的集群上启用调度

kubectl taint nodes --all node-role.kubernetes.io/master-

1.4. 安装pod网络插件

使用kubectl选择合适的网络组件

kubectl apply -f <add-on.yaml>

每个群集只能安装一种pod网络插件,且每个群集必需有一个pod网络插件,使得pods之间可以通讯

1.4.1. 使用 flannel插件

要求:

  1. 再执行 kubeadm init 时添加--pod-network-cidr=10.244.0.0/16参数

For flannel to work correctly, you must pass --pod-network-cidr=10.244.0.0/16 to kubeadm init.

# kubeadm init --pod-network-cidr=10.244.0.0/16
kubeadm init --pod-network-cidr=10.244.0.0/16 --image-repository=registry.aliyuncs.com/google_containers --apiserver-bind-port=6443
  1. 设IPv4流量通过路由表
sysctl net.bridge.bridge-nf-call-iptables=1 
  1. 确保防火墙规则允许参与覆盖网络的所有主机的UDP端口8285和8472通信
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml

基于阿里云镜像的kube-flannel 配置文件,参考github

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: flannel
rules:
  - apiGroups:
      - ""
    resources:
      - pods
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes/status
    verbs:
      - patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flannel
  namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-system
  labels:
    tier: node
    app: flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "type": "flannel",
      "delegate": {
        "hairpinMode": true,
        "isDefaultGateway": true
      }
    }
  net-conf.json: |
    {
      "Network": "10.24.0.0/16",
      "Backend": {
        "Type": "ali-vpc"
      }
    }
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: kube-flannel-ds
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      hostNetwork: true
      nodeSelector:
        beta.kubernetes.io/arch: amd64
      tolerations:
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: registry.cn-hangzhou.aliyuncs.com/google-containers/flannel:v0.9.0
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conf
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: registry.cn-hangzhou.aliyuncs.com/google-containers/flannel:v0.9.0
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: true
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg

1.5. Worknode 加入

在worknode 上运行以下命令 加入集群

kubeadm join 172.24.195.43:6443 --token bdibtv.8iu07mfcpssfdrmg \
    --discovery-token-ca-cert-hash sha256:6732957bd86580ac23b70bb7a1a0135149db580e3f25a7ce24c4c1409cd5b923

kubeadm join 192.168.1.66:6443 --token 8wnr18.w4d1q0tybbyf02mv \
--discovery-token-ca-cert-hash sha256:4096879f382499fa82a935e7c10ded9c14fe56c155eef0b1170f2839d09489c5

1.6. 安装遇到的问题汇总

1.6.1. not-ready

https://stackoverflow.com/questions/47107117/how-to-debug-when-kubernetes-nodes-are-in-not-ready-state

1.7. 其他

  1. kubelet会 自动重启
    The kubelet is now restarting every few seconds, as it waits in a crashloop for kubeadm to tell it what to do.
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --cgroup-driver=cgroupfs"

systemctl enable kubelet.service
systemctl start kubelet.service
  1. 配置 kubelet 的容器驱动

当使用 docker 作为容器的时候, kubeadm 会自动检测 给以kubelet进程的Cgroup 驱动。相关设置在 /var/lib/kubelet/kubeadm-flags.env

该文件会在执行 kubeadm initkubeadm join 的时候使用

cat <<EOF > rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: default-rbac
subjects:
- kind: ServiceAccount
  name: default
  namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
EOF

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
helm init
kubectl apply -f rbac.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml
kubectl create clusterrolebinding kubernetes-dashboard --clusterrole=cluster-admin --serviceaccount=kube-system:kubernetes-dashboard

1.7.1. 进程对硬件资源使用的限制(cgroups)

Cgroup是control group的简写,属于Linux内核提供的一个特性,用于限制和隔离一组进程对系统资源的使用,也就是做资源QoS,这些资源主要包括CPU、内存、block I/O和网络带宽。Cgroup从2.6.24开始进入内核主线,目前各大发行版都默认打开了Cgroup特性。
Cgroups提供了以下四大功能:

  1. 资源限制(Resource Limitation):cgroups可以对进程组使用的资源总额进行限制。如设定应用运行时使用内存的上限,一旦超过这个配额就发出OOM(Out of Memory)。
  2. 优先级分配(Prioritization):通过分配的CPU时间片数量及硬盘IO带宽大小,实际上就相当于控制了进程运行的优先级。
  3. 资源统计(Accounting): cgroups可以统计系统的资源使用量,如CPU使用时长、内存用量等等,这个功能非常适用于计费。
  4. 进程控制(Control):cgroups可以对进程组执行挂起、恢复等操作。

第三方管理安装工具

推荐查阅
https://github.com/easzlab/kubeasz

2. 卸载

kubeadm reset
sudo apt-get purge kubeadm kubectl kubelet kubernetes-cni
sudo apt-get autoremove  
sudo rm -rf ~/.kube

公有云上部署 kuberneters

公有云
在公有云上使用kubeasz部署k8s集群需要注意以下几个常见问题。

安全组
注意虚机的安全组规则配置,一般集群内部节点之间端口放开即可;

网络组件
一般公有云对网络限制较多,跨节点 pod 通讯需要使用 OVERLAY 添加报头;比如可以使用如下:(kubeasz 项目中已默认配置)

flannel 使用 vxlan 模式:roles/flannel/defaults/main.yml
calico 开启 ipinip:roles/calico/defaults/main.yml
kube-router 开启 ipinip:roles/kube-router/defaults/main.yml
节点公网访问
可以在安装时每个节点绑定弹性公网地址(EIP),装完集群解绑;也可以开通NAT网关,或者利用iptables自建上网网关等方式

负载均衡
一般云厂商会限制使用keepalived+haproxy自建负载均衡,你可以根据云厂商文档使用云负载均衡(内网)四层TCP负载模式;

kubeasz 2x 版本已无需依赖外部负载均衡实现apiserver的高可用,详见 2x架构
kubeasz 1x 及以前版本需要负载均衡实现apiserver高可用,详见 1x架构
时间同步
一般云厂商提供的虚机都已默认安装时间同步服务,无需自行安装。

访问 APISERVER
在公有云上安装完集群后,需要在公网访问集群 apiserver,而我们在安装前可能没有规划公网IP或者公网域名;而 apiserver 肯定需要 https 方式访问,在证书创建时需要加入公网ip/域名;可以参考这里修改 APISERVER(MASTER)证书

在公有云上部署多主高可用集群
处理好以上讨论的常见问题后,在公有云上使用 kubeasz 安装集群与自有环境没有差异。

使用 kubeasz 2x 版本安装单节点、单主多节点、多主多节点 k8s 集群,云上云下的预期安装体验完全一致


如果你觉得这篇文章对你有帮助,不妨请我喝杯咖啡,鼓励我创造更多!