ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## 0. 核心组件 * etcd 保存了整个集群的状态; * kube-apiserver 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制; * kube-controller-manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等; * kube-scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上; * kubelet 负责维持容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理; * Container runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI),默认的容器运行时为 Docker * kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡 ![](https://carey-akhack-com.oss-cn-hangzhou.aliyuncs.com/images/20190417/components.png) ### 0.1 插件 * kube-dns 负责为整个集群提供 DNS 服务 * Ingress Controller 为服务提供外网入口 * Heapster 提供资源监控 * Dashboard 提供 GUI * Federation 提供跨可用区的集群 * Fluentd-elasticsearch 提供集群日志采集、存储与查询 ## 1\. 准备环境 Kubernetes 架构图 ![](https://carey-akhack-com.oss-cn-hangzhou.aliyuncs.com/images/20190417/kubernetes%E5%9F%BA%E7%A1%80%E6%9E%B6%E6%9E%84%E5%9B%BE.jpg) ### 1.1 配置hosts ``` cat /etc/hosts 10.0.20.145 k8s-145 10.0.20.146 k8s-146 10.0.20.147 k8s-147 10.0.20.148 k8s-148 ``` ### 升级内核(可选) ``` # 导入 Key rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org # 安装 Yum 源 rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm # 更新 kernel yum --enablerepo=elrepo-kernel install -y kernel-lt kernel-lt-devel # 配置 内核优先 grub2-set-default 0 ``` ### 1.2 配置python ``` yum install epel-release -y yum -y install sshpass yum install python git python-pip -y pip install pip --upgrade -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com pip install --no-cache-dir ansible -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com ``` ### 1.3 配置ansible ``` git clone https://gitee.com/careyjike_173/k8s_install.git /etc/ansible cd /etc/ansible ``` ``` [deploy] 10.0.20.145 [etcd] 10.0.20.145 NODE_NAME=etcd1 10.0.20.146 NODE_NAME=etcd2 10.0.20.147 NODE_NAME=etcd3 [node] 10.0.20.148 [master] 10.0.20.145 # CA 证书相关参数 CA_EXPIRY="876000h" CERT_EXPIRY="438000h" # 二进制文件目录 bin_dir="/usr/local/kubernetes/bin" # 证书目录 ca_dir="/usr/local/kubernetes/ssl" # 部署目录 base_dir="/etc/ansible" ``` ### 1.4 初始化系统 ``` ansible-playbook 01init_os.yaml ``` ### 2\. 安装etcd 这里使用外置`etcd` ### 2.1 生成etcd证书 ``` ansible-playbook 02certificate.yaml ``` ### 2.2 配置etcd - `--auto-compaction-retention` 由于ETCD数据存储多版本数据,随着写入的主键增加历史版本需要定时清理,默认的历史数据是不会清理的,数据达到2G就不能写入,必须要清理压缩历史数据才能继续写入;所以根据业务需求,在上生产环境之前就提前确定,历史数据多长时间压缩一次;推荐一小时压缩一次数据这样可以极大的保证集群稳定,减少内存和磁盘占用 - `--max-request-bytes` etcd Raft消息最大字节数,ETCD默认该值为1.5M; 但是很多业务场景发现同步数据的时候1.5M完全没法满足要求,所以提前确定初始值很重要;由于1.5M导致我们线上的业务无法写入元数据的问题,我们紧急升级之后把该值修改为默认32M,但是官方推荐的是10M,大家可以根据业务情况自己调整 - `--quota-backend-bytes` ETCD db数据大小,默认是2G,当数据达到2G的时候就不允许写入,必须对历史数据进行压缩才能继续写入;参加1里面说的,我们启动的时候就应该提前确定大小,官方推荐是8G,这里我们也使用8G的配置 ``` ansible-playbook 03etcd.yaml ``` ### 2.3 验证etcd群集 ``` /usr/local/kubernetes/bin/etcdctl --endpoints=https://etcd1-ip:2379,https://etcd2-ip:2379,https://etcd3-ip:2379 --cert-file=/usr/local/kubernetes/ssl/etcd.pem --key-file=/usr/local/kubernetes/ssl/etcd-key.pem --ca-file=/usr/local/kubernetes/ssl/ca.pem cluster-health ``` ## 3\. 所有节点安装Docker/kubeadm/kubelet Kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker。 ### 3.1 安装Docker ``` ansible-playbook 04docker.yaml ``` ### 3.2 添加阿里云YUM软件源 ``` $ 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 ``` ### 3.3 安装kubeadm,kubelet和kubectl 由于版本更新频繁,这里指定版本号部署: ``` $ yum install -y kubelet-1.13.3 // 这里指定版本应为依赖问题需分开yum安装 $ yum install -y kubeadm-1.13.3 kubectl-1.13.3 $ systemctl enable kubelet ``` ## 4\. 配置nginx `kube-apiserver`高可用可以直接起多个节点,很多使用`keepalive`,`haproxy`来进行高可用配置,但是在大部分的**公有云上无法使用`vip`**。公有云上可以使用公有云提供的`LoadBalance`,这里我们使用`nginx`来代替 ### 4.1 安装nginx [**ngx stream core module**](http://nginx.org/en/docs/stream/ngx_stream_core_module.html) ``` yum -y install nginx nginx-mod-stream ``` * nginx stream 四层协议的转发、代理或者负载均衡 ### 4.2 配置高可用kube-apiserver ``` stream { log_format main '$remote_addr [$time_local]' '$protocol $status $bytes_sent $bytes_received' '$session_time'; server { listen 7443; proxy_pass kubeapi; access_log /var/log/nginx/access.log main; } upstream kubeapi { server 10.0.20.145:6443; server 10.0.20.146:6443; server 10.0.20.147:6443; } } ``` ## 4\. 部署Kubernetes Master ### 4.1 配置初始化参数 ``` cat kubeadmin-config.yaml apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration kubernetesVersion: "v1.13.3" controlPlaneEndpoint: "10.0.20.145:6443" dns: type: "CoreDNS" networking: serviceSubnet: "10.1.0.0/16" podSubnet: "10.244.0.0/16" imageRepository: registry.aliyuncs.com/google_containers etcd: external: endpoints: - https://10.0.20.145:2379 - https://10.0.20.146:2379 - https://10.0.20.147:2379 caFile: /usr/local/kubernetes/ssl/ca.pem certFile: /usr/local/kubernetes/ssl/etcd.pem keyFile: /usr/local/kubernetes/ssl/etcd-key.pem --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: ipvs ``` ### 4.2 初始化master ``` $ kubeadm init --config=kubeadm-config.yaml ``` ### 4.3 使用kubectl工具: ``` mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config kubectl get nodes ``` ### 4.4 手动复制证书到其他master节点 ``` scp -r /etc/kubernetes/pki k8s-146:/etc/kubernetes/ scp -r /etc/kubernetes/pki k8s-147:/etc/kubernetes/ scp -r /etc/kubernetes/admin.conf k8s-146:/etc/kubernetes/admin.conf scp -r /etc/kubernetes/admin.conf k8s-147:/etc/kubernetes/admin.conf ``` ## 5\. 安装Pod网络插件(CNI) ``` $ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml ``` 确保能够访问到quay.io这个registery。 ## 6\. 加入Kubernetes Master,Node 向集群添加新节点,执行在kubeadm init输出的kubeadm join命令: ## 6.1 添加master * `--experimental-control-plane` 创建一个master ``` kubeadm join 10.0.20.145:6443 --token 2xj72s.amdni1llci0t3mps --discovery-token-ca-cert-hash sha256:e051468f218d08e0edfaf090a54eb5747df3ff42cb77f930bcc4789aeffcd702 --experimental-control-plane --apiserver-advertise-address 10.0.20.145 # 指定本机IP ``` ### 6.2 添加node ``` kubeadm join 10.0.20.145:6443 --token 2xj72s.amdni1llci0t3mps --discovery-token-ca-cert-hash sha256:e051468f218d08e0edfaf090a54eb5747df3ff42cb77f930bcc4789aeffcd702 ``` ## 7\. 测试kubernetes集群 在Kubernetes集群中创建一个pod,验证是否正常运行: ``` $ kubectl create deployment nginx --image=nginx $ kubectl expose deployment nginx --port=80 --type=NodePort $ kubectl get pod,svc ``` 访问地址:[http://NodeIP](http://NodeIP):Port ## 8\. 部署 Dashboard ``` $ kubectl apply -f kubernetes-dashboard.yaml ``` 访问地址:[http://NodeIP:30001](http://NodeIP:30001) 创建`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。 ## 9\. kubectl 命令自动补全 ``` source <(kubectl completion bash) ``` 如报错: **`bash: _get_comp_words_by_ref:` 未找到命令**执行`source /etc/profile.d/bash_completion.sh`或`source /etc/bash_completion`再执行`source <(kubectl completion bash)`即可 ## 10\. 问题记录 ### 10.1 kubeadm token过期后加入新节点 默认`token`的有效期为`24`小时,当过期之后,该`token`就不可用了 * 重新生成`token` ``` [root@k8s-12 ~]# kubeadm token create tczji2.wpk4wx9utlu08snq ``` * 获取`ca`证书`sha256`编码`hash`值 ``` [root@k8s-12 ~]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' 792a25d32c75c63e4da6586bcd05969da6d8284f23ee22612a3d4213b148ee0e ``` * 节点加入集群 >[danger] 具体参考`6.1`这里需要复制证书相关,具体参考`4.4` ``` kubeadm join 10.0.20.11:7443 --token tczji2.wpk4wx9utlu08snq --discovery-token-ca-cert-hash sha256:792a25d32c75c63e4da6586bcd05969da6d8284f23ee22612a3d4213b148ee0e --experimental-control-plane --apiserver-advertise-address 10.0.20.11 ``` ---- [**官方文档**](https://kubernetes.io/docs/setup/independent/high-availability/)