• kubeadm安装kubernetes 1.16.2


    简介

    当前kubernetes的最新版本已经到了1.16,而kubernetes官方推出的安装工具kubeadm也已经GA。本文就基于kubeadm来安装最新的kubernetes集群。

    各组件示意图如下:

    k8s-component

    环境说明

    部署环境:

    主机名 ip地址 节点类型 系统版本
    master.example.com 192.168.0.1 master、etcd centos7
    node1.example.com 192.168.0.2 node centos7

    相关组件版本说明:

    组件 版本 说明
    kubernetes 1.16.2 主程序
    docker 19.03.3 容器
    flannel 0.11.0 网络插件
    etcd 3.3.15 数据库
    coredns 1.6.2 dns组件
    kubernetes-dashboard 2.0.0-beta5 web界面
    ingress-nginx 0.26.1 ingress

    安装

    安装步骤说明:

    • 配置主机名、防火墙、yum源
    • 配置内核参数
    • 加载内核模块
    • 安装Docker
    • 安装kubelet、kubectl、kubeadm
    • 编辑kubeadm-config.yml文件
    • 安装master节点
    • 配置网络插件
    • 添加node节点
    • 安装addons之kubernetes dashboard
    • 安装ingress

    准备基础环境

    修改主机名:

    hostnamectl set-hostname master.example.com --static
    hostnamectl set-hostname node1.example.com --static
    

    清空防火墙规则和selinux:

    iptables -F
    setenforce 0 
    

    设置yum源:

    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
    wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
    

    修改内核参数:

    # cat  /etc/sysctl.conf
    net.ipv.ip_forward = 1
    
    sysctl -p 
    
    

    加载内核模块:

    
    cat > /etc/sysconfig/modules/ipvs.modules <<EOF
    #!/bin/bash
    modprobe -- br_netfilter
    modprobe -- ip_vs
    modprobe -- ip_vs_rr
    modprobe -- ip_vs_wrr
    modprobe -- ip_vs_sh
    modprobe -- nf_conntrack_ipv4
    EOF
    
    chmod 755 /etc/sysconfig/modules/ipvs.modules && 
    bash /etc/sysconfig/modules/ipvs.modules && 
    lsmod | grep -E "ip_vs|nf_conntrack_ipv4"
    
    

    安装docker

    yum install -y yum-utils
    
    yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
    yum install -y docker-ce
    
    mkdir /etc/docker
    
    cat > /etc/docker/daemon.json << EOF
    {
        "exec-opts": ["native.cgroupdriver=systemd"],
        "log-driver": "json-file",
        "log-opts": {
            "max-size": "100m",
            "max-file": "10"
        },
        "bip": "169.254.123.1/24",
        "oom-score-adjust": -1000,
        "registry-mirrors": ["https://pqbap4ya.mirror.aliyuncs.com"],
        "storage-driver": "overlay2",
        "storage-opts":["overlay2.override_kernel_check=true"],
        "live-restore": false
    }
    EOF
    
    systemctl restart docker
    systemctl enable docker
    
    

    安装kubeadm、kubelet、kubectl

    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=0
    repo_gpgcheck=0
    gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
    EOF
    
    yum install -y kubelet kubeadm kubectl
    
    

    配置kubeadm-config.yaml

    通过如下指令创建默认的kubeadm-config.yaml文件:

    kubeadm config print init-defaults  > kubeadm-config.yaml
    

    kubeadm-config.yaml组成部署说明:

    • InitConfiguration: 用于定义一些初始化配置,如初始化使用的token以及apiserver地址等
    • ClusterConfiguration:用于定义apiserver、etcd、network、scheduler、controller-manager等master组件相关配置项
    • KubeletConfiguration:用于定义kubelet组件相关的配置项
    • KubeProxyConfiguration:用于定义kube-proxy组件相关的配置项

    可以看到,在默认的kubeadm-config.yaml文件中只有InitConfiguration、ClusterConfiguration 两部分。我们可以通过如下操作生成另外两部分的示例文件:

    # 生成KubeletConfiguration示例文件 
    kubeadm config print init-defaults --component-configs KubeletConfiguration
    
    # 生成KubeProxyConfiguration示例文件 
    kubeadm config print init-defaults --component-configs KubeProxyConfiguration
    

    最终修改kubeadm-config.yaml文件如下:

    apiVersion: kubeadm.k8s.io/v1beta2
    bootstrapTokens:
    - groups:
      - system:bootstrappers:kubeadm:default-node-token
      token: abcdef.0123456789abcdef
      ttl: 24h0m0s
      usages:
      - signing
      - authentication
    kind: InitConfiguration
    localAPIEndpoint:
      advertiseAddress: 192.168.0.1
      bindPort: 6443
    nodeRegistration:
      criSocket: /var/run/dockershim.sock
      name: master.example.com
      taints:
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
    ---
    apiServer:
      timeoutForControlPlane: 4m0s
      bind-address: 172.26.159.88
      secure-port: 6443
      authorization-mode: Node,RBAC
      runtime-config: "api/all=true"
      kubelet-https: true
      anonymous-auth: false
      requestheader-allowd-names: ""
      requestheader-extra-headers-prefix: "X-Remote-Extra-"
      requestheader-group-headers: X-Remote-Group
      requestheader-username-headers: X-remote-User
      disable-admission-plugins: PersistentVolumeLabel
      enable-admission-plugins: NodeRestriction
      enable-swagger-ui: true
      allow-privileged: true
      audit-log-maxage: 30
      audit-log-maxbackup: 3
      audit-log-maxsize: 100
      event-ttl: 1h
      v: 2
      logtostderr: true
    apiVersion: kubeadm.k8s.io/v1beta2
    certificatesDir: /etc/kubernetes/pki
    clusterName: kubernetes
    controllerManager:
      address: 127.0.0.1
      node-monitor-grace-period: 40s
      node-monitor-period: 5s
      pod-eviction-timeout: 1m0s
      controllers: "*,bootstrapsigner,tokencleaner"
      horizontal-pod-autoscaler-use-rest-clients: true      
    dns:
      type: CoreDNS
    etcd:
      local:
        dataDir: /var/lib/etcd
    imageRepository: gcr.azk8s.cn/google_containers
    kind: ClusterConfiguration
    kubernetesVersion: v1.16.2
    networking:
      dnsDomain: cluster.local
      serviceSubnet: 10.96.0.0/16
      podSubnet: 10.244.0.0/16
    scheduler:
      leader-elect: true
      address: 127.0.0.1
      v: 2
      logtostderr: true
    ---
    apiVersion: kubeproxy.config.k8s.io/v1alpha1
    kind: KubeProxyConfiguration
    imageRepository: gcr.azk8s.cn/google_containers
    kubeProxy:
      config:
        featureGates:
          SupportIPVSProxyMode: true
        mode: ipvs
    ---
    apiVersion: kubelet.config.k8s.io/v1beta1
    kind: KubeletConfiguration
    clusterDNS:
    - 10.96.0.10
    
    

    关于kubeadm-config.yaml更多配置语法参考: https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2

    使用kubeadm-config.yaml配置主节点:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/control-plane-flags/

    kube-proxy开启ipvs参考: https://github.com/kubernetes/kubernetes/blob/master/pkg/proxy/ipvs/README.md

    kubelet的配置示例参考: https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/kubelet-integration/#configure-kubelets-using-kubeadm

    部署master

    安装master节点:

    kubeadm init --config kubeadm-config.yaml
    

    配置访问集群:

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

    完成部署之后,发现两个问题:

    1. master节点一直notready
    2. coredns pod一直pending

    其实这两个问题都是因为还没有安装网络插件导致的,接下来开始安装网络插件

    安装flannel网络插件

    
    wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
    
    sed -i 's@quay.io/coreos@quay.azk8s.cn/coreos@g' kube-flannel.yml
    
    kubectl apply -f kube-flannel.yml
    
    

    添加节点

    生成用于添加节点的kubeadm-config.yaml文件

    kubeadm config print join-defaults > kubeadm-config.yaml
    
    # kubeadm-config.yaml内容如下:
    
    apiVersion: kubeadm.k8s.io/v1beta2
    caCertPath: /etc/kubernetes/pki/ca.crt
    discovery:
      bootstrapToken:
        apiServerEndpoint: kube-apiserver:6443
        token: abcdef.0123456789abcdef
        unsafeSkipCAVerification: true
      timeout: 5m0s
      tlsBootstrapToken: abcdef.0123456789abcdef
    kind: JoinConfiguration
    nodeRegistration:
      criSocket: /var/run/dockershim.sock
      name: node1.example.com
      taints: null
    
    

    这里需要修改三个地方:

    1. apiServerEndpoint:连接apiserver的地址,即master的api地址,这里可以改为192.168.0.1:6443,如果master集群部署的话,这里需要改为集群vip地址
    2. token及tlsBootstrapToken:连接master使用的token,这里需要与master上的InitConfiguration中的token配置一致
    3. name:node节点的名称,如果使用主机名,需要确保master节点可以解析该主机名。否则的话可直接使用ip地址

    添加节点:

    kubeadm join --config kubeadm-config.yaml
    

    需要说明的是,添加node节点,也可以直接使用master安装完成时给出的添加方式,类似如下:kubeadm join 192.168.0.1:6443 --token abcdef.0123456789abcdef
    --discovery-token-ca-cert-hash sha256:cad3fa778559b724dff47bb1ad427bd39d97dd76e934b9467507a2eb990a50c7

    安装dashboard

    dashboard的github仓库地址:https://github.com/kubernetes/dashboard

    代码仓库当中,有给出安装示例的相关部署文件,我们可以直接获取之后,直接部署即可:

    wget https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended.yaml
    kubectl apply -f ./recommended.yaml
    

    默认这个部署文件当中,会单独创建一个名为kubernetes-dashboard的命名空间,并将kubernetes-dashboard部署在该命名空间下。dashboard的镜像来自docker hub官方,所以可不用修改镜像地址,直接从官方获取即可。

    但是在默认情况下,dashboard并不对外开放访问端口,我这里简化操作,直接使用nodePort的方式将其端口暴露出来,修改serivce部分的定义:

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

    重新创建service:

    kubectl delete svc kubernetes-dashboard -n kubernetes-dashboard
    kubectl apply -f ./recommended.yaml
    

    此时,即可通过浏览器访问web端,端口为32443:

    kubernetes-dashboard

    可以看到出现如上图画面,需要我们输入一个kubeconfig文件或者一个token。事实上在安装dashboard时,也为我们默认创建好了一个serviceaccount,为kubernetes-dashboard,并为其生成好了token,我们可以通过如下指令获取该sa的token:

     kubectl describe secret -n kubernetes-dashboard $(kubectl get secret -n kubernetes-dashboard |grep  kubernetes-dashboard-token | awk '{print $1}') |grep token | awk '{print $2}'
     
     
     eyJhbGciOiJSUzI1NiIsImtpZCI6IkUtYTBrbU44TlhMUjhYWXU0VDZFV1JlX2NQZ0QxV0dPRjBNUHhCbUNGRzAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291eeeeeeLWRhc2hib2FyZC10b2tlbi1rbXBuMiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFxxxxxxxxxxxxxxxxxxxxxxxGZmZmYxLWJhOTAtNDU5Ni1hMzgxLTRhNDk5NzMzYWI0YiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDprdWJlcm5ldGVzLWRhc2hib2FyZCJ9.UwAsemOra-EGl2OzKc3lur8Wtg5adqadulxH7djFpmpWmDj1b8n1YFiX-AwZKSbv_jMZd-mvyyyyyyyyyyyyyyyMYLyVub98kurq0eSWbJdzvzCvBTXwYHl4m0RdQKzx9IwZznzWyk2E5kLYd4QHaydCw7vH26by4cZmsqbRkTsU6_0oJIs0YF0YbCqZKbVhrSVPp2Fw5IyVP-ue27MjaXNCSSNxLX7GNfK1W1E68CrdbX5qqz0-Ma72EclidSxgs17T34p9mnRq1-aQ3ji8bZwvhxuTtCw2DkeU7DbKfzXvJw9ENBB-A0fN4bewP6Og07Q
    

    通过该token登入集群以后,发现很多namespace包括一些其他的资源都没有足够的权限查看。这是因为默认我们使用的这个帐户只有有限的权限。我们可以通过对该sa授予cluster-admin权限来解决这个问题:

    修改ClusterRoleBinding资源内容如下:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: kubernetes-dashboard
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
      - kind: ServiceAccount
        name: kubernetes-dashboard
        namespace: kubernetes-dashboard
    

    重新创建clusterrolebinding:

    kubectl delete clusterrolebindgin  kubernetes-dashboard -n kubernetes-dashboard
    kubectl apply -f ./recommended.yaml
    

    此时,kubernetes-dashboard相关配置即完成。

    部署ingress

    ingress提供外部访问kubernetes内部应用的入口。社区提供众多的组件实现,这里就直接使用官方的ingress-nginx组件。

    github仓库地址:

    和dashboard一样,代码仓库当中也提供部署文件示例,我们直接获取即可:

    wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
    

    获取到部署文件之后,还需要改两个东西:

    1. 替换镜像地址
    sed -i 's/quay.io/quay.azk8s.cn/g' mandatory.yaml
    
    1. 默认ingress会监听在80和443端口,我们需要让其监听在宿主机的80和443上,以实现外部访问,修改deployment资源,添加一个hostNetwork: true配置项:
    ...
          hostNetwork: true
          containers:
            - name: nginx-ingress-controller
              image: quay.azk8s.cn/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1
              args:
                - /nginx-ingress-controller
                - --configmap=$(POD_NAMESPACE)/nginx-configuration
                - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
                - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
                - --publish-service=$(POD_NAMESPACE)/ingress-nginx
                - --annotations-prefix=nginx.ingress.kubernetes.io
    ...
    

    部署:

    kubectl apply -f ./mandatory.yaml
    
    

    同样的,该文件会创建一个名为ingress-nginx的命名空间,并部署ingress-nginx pod至该命名空间下。

    [root@master ~]# kubectl get pods -n ingress-nginx
    NAME                                       READY   STATUS    RESTARTS   AGE
    nginx-ingress-controller-8fbcc4d76-vvgj5   1/1     Running   0          3m9s
    

    默认情况下,ingress容器可随意在节点间调度,这样其实也存在一个问题,作为外部的访问入口,如果无法确定ingress容器所在的节点ip,则等于找不到入口。一个有效的解决方法是通过打标签的方式将ingress固定在特定的节点上,并且通过污点和容忍将这些特定节点上的其他应用排干,只用于入口流量转发

    重置集群

    下面给出重置集群的方法:

    kubeadm reset
    ifconfig cni0 down
    ip link delete cni0
    ifconfig flannel.1 down
    ip link delete flannel.1
    rm -rf /var/lib/cni/
    
    
  • 相关阅读:
    tab下图片要求
    segmentController
    下拉加载更多
    获取用户信息
    时间选择器
    JavaScript标准库之 ----  Object
    JavaScript标准库之——JSON
    JavaScript标准库之
    post网络请求坑
    构造一个简单的Linux系统MenuOS
  • 原文地址:https://www.cnblogs.com/breezey/p/11770780.html
Copyright © 2020-2023  润新知