一直想写点内容,来记录我在IT这条路上的旅程。这个念头持续了很久。终于在2019年的7月21日成行。
我将我在IT这条路上的所学、所做、所闻当作旅途中的所看、所听、所感,一一记录下来。
IT是一条不归路。高手之上还有高手。而我单单的希望和越来越强的前辈过招。
我将我的IT方向,轨到容器开发。容器是容器生态圈的简称,开发是Go语言开发的简称。
我个人认为运维的趋势是容器化运维,开发的趋势是容器化开发。所以我走的是容器开发的路。
今年是相对悠闲的一年,可以沉下心来做两件大事:1.我的容器生态圈之旅2.Go语言从小白到大神之旅
我希望的是用时6个月初步达到容器开发的级别,因为我具备一定的基础,应该还是可以的。
我希望的是在2020年的5月份时,可以初步完成这两件大事。
IcandoitbecauseI'myoung!
笔落心坚。拭目以待。
硬件性能
从上图可以看出来:硬件内存达到24.0GB,所以可以支持开启众多虚拟机,更有效的模拟真实生成环境。
VMwareWorkstationPro14
Xshell可以在Windows界面下用来访问远端不同系统下的服务器,从而比较好的达到远程控制终端的目的。除此之外,其还有丰富的外观配色方案以及样式选择。
查看系统版本和内核
[root@mobanji~]#cat/etc/redhat-releaseCentOSLinuxrelease7.6.1810(Core)[root@mobanji~]#uname-r3.10.0-957.el7.x86_64别名设置
#进入网络配置文件[root@mobanji~]#yuminstall-yvim[root@mobanji~]#aliasvimn="vim/etc/sysconfig/network-scripts/ifcfg-eth0"[root@mobanji~]#vim~/.bashrcaliasvimn="vim/etc/sysconfig/network-scripts/ifcfg-eth0"网络优化
[root@mobanji~]#vimnTYPE=EthernetBOOTPROTO=noneNAME=eth0DEVICE=eth0ONBOOT=yesIPADDR=20.0.0.5PREFIX=24GATEWAY=20.0.0.2DNS1=233.5.5.5DNS2=8.8.8.8DNS3=119.29.29.29DNS4=114.114.114.114更新yum源及必要软件安装
[root@mobanji~]#sed-i'79s@GSSAPIAuthenticationyes@GSSAPIAuthenticationno@;115s@#UseDNSyes@UseDNSno@'/etc/ssh/sshd_config[root@mobanji~]#systemctlrestartsshd关闭防火墙和SElinux
#关闭防火墙,清理防火墙规则,设置默认转发策略[root@mobanji~]#systemctlstopfirewalld[root@mobanji~]#systemctldisablefirewalldRemovedsymlink/etc/systemd/system/multi-user.target.wants/firewalld.service.Removedsymlink/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.[root@mobanji~]#iptables-F&&iptables-X&&iptables-F-tnat&&iptables-X-tnat[root@mobanji~]#iptables-PFORWARDACCEPT[root@mobanji~]#firewall-cmd--statenotrunning关闭SELinux,否则后续K8S挂载目录时可能setenforce0报错Permissiondenied[root@mobanji~]#setenforce0[root@mobanji~]#sed-i's/^SELINUX=.*/SELINUX=disabled/'/etc/selinux/config关闭无关的服务
[root@mobanji~]#systemctllist-unit-files|grep"enabled"[root@mobanji~]#systemctlstatuspostfix&&systemctlstoppostfix&&systemctldisablepostfix设置limits.conf
[root@mobanji~]#cat>>/etc/security/limits.conf< CentOS7.x系统自带的3.10.x内核存在一些Bugs,导致运行的Docker、Kubernetes不稳定,例如: ->高版本的docker(1.13以后)启用了3.10kernel实验支持的kernelmemoryaccount功能(无法关闭),当节点压力大如频繁启动和停止容器时会导致cgroupmemoryleak; ->网络设备引用计数泄漏,会导致类似于报错:"kernel:unregister_netdevice:waitingforeth0tobecomefree.Usagecount=1"; 解决方案如下: ->升级内核到4.4.X以上; ->或者,手动编译内核,disableCONFIG_MEMCG_KMEM特性; ->或者安装修复了该问题的Docker18.09.1及以上的版本。但由于kubelet也会设置kmem(它vendor了runc),所以需要重新编译kubelet并指定GOFLAGS="-tags=nokmem"; #查看默认启动顺序[root@mobanji~]#awk-F\''$1=="menuentry"{print$2}'/etc/grub2.cfgCentOSLinux(4.4.185-1.el7.elrepo.x86_64)7(Core)CentOSLinux(3.10.0-957.21.3.el7.x86_64)7(Core)CentOSLinux(3.10.0-957.el7.x86_64)7(Core)CentOSLinux(0-rescue-b4c601a613824f9f827cb9787b605efb)7(Core)由上面可以看出新内核(4.4.185)目前位置在0,原来的内核(3.10.0)目前位置在1,所以如果想生效最新的内核,还需要我们修改内核的启动顺序为0 #编辑/etc/default/grub文件[root@mobanji~]#vim/etc/default/grubGRUB_DEFAULT=0<---saved改为0#运行grub2-mkconfig命令来重新创建内核配置#重启系统[root@mobanji~]#reboot关闭NUMA [root@mobanji~]#cp/etc/default/grub{,.bak}[root@mobanji~]#vim/etc/default/grub.........GRUB_CMDLINE_LINUX="......numa=off"#即添加"numa=0ff"内容重新生成grub2配置文件:#cp/boot/grub2/grub.cfg{,.bak}#grub2-mkconfig-o/boot/grub2/grub.cfg设置rsyslogd和systemdjournald systemd的journald是Centos7缺省的日志记录工具,它记录了所有系统、内核、ServiceUnit的日志。相比systemd,journald记录的日志有如下优势: ->可以记录到内存或文件系统;(默认记录到内存,对应的位置为/run/log/jounal); ->可以限制占用的磁盘空间、保证磁盘剩余空间; ->journald默认将日志转发给rsyslog,这会导致日志写了多份,/var/log/messages中包含了太多无关日志,不方便后续查看,同时也影响系统性能。 [root@mobanji~]#cat>/etc/sysconfig/modules/ipvs.modules< [root@mobanji~]#cat< 必须关闭tcp_tw_recycle,否则和NAT冲突,会导致服务不通; 关闭IPV6,防止触发dockerBUG; 个性vim配置 #脚本目录[root@mobanji~]#mkdir-p/service/scripts至此:模板机优化完毕 节点名称 IP 安装软件 角色 jumpserver 20.0.0.200 堡垒机 k8s-master01 20.0.0.201 kubeadm、kubelet、kubectl、docker、etcd master节点 k8s-master02 20.0.0.202 ceph k8s-master03 20.0.0.203 k8s-node01 20.0.0.204 kubeadm、kubelet、kubectl、docker 业务节点 k8s-node02 20.0.0.205 k8s-node03 20.0.0.206 k8s-ha01 20.0.0.207 20.0.0.208 VIP:20.0.0.250 haproxy、keepalived、ceph VIP k8s-ha02 k8s-ceph 20.0.0.209 存储节点 以k8s-master01为例 #改主机名[root@mobanji~]#hostnamectlset-hostnamek8s-master01[root@mobanji~]#bash[root@k8s-master01~]##改IP[root@k8s-master01~]#vimnTYPE=EthernetBOOTPROTO=noneNAME=eth0DEVICE=eth0ONBOOT=yesIPADDR=20.0.0.201PREFIX=24GATEWAY=20.0.0.2DNS1=223.5.5.5[root@k8s-master01~]#systemctlrestartnetwork[root@k8s-master01~]#pingwww.baidu.comPINGwww.baidu.com(61.135.169.121)56(84)bytesofdata.64bytesfrom61.135.169.121(61.135.169.121):icmp_seq=1ttl=128time=43.3ms^C---www.baidu.compingstatistics---1packetstransmitted,1received,0%packetloss,time0msrttmin/avg/max/mdev=43.348/43.348/43.348/0.000ms[root@k8s-master01~]#hostname-I20.0.0.201注:init0-->快照至此:虚机准备完毕 以k8s-ha01为例 [root@k8s-ha01~]#systemctlstopkeepalived#刷新浏览器[root@k8s-ha01~]#systemctlstartkeepalived[root@k8s-ha01~]#systemctlstophaproxy#刷新浏览器1.5.2部署kubernetes集群1.5.2.1虚机初始化以k8s-master01为例 为每台虚机添加host解析记录 [root@k8s-master01~]#cat>>/etc/hosts< [root@k8s-master01~]#swapoff-a[root@k8s-master01~]#yes|cp/etc/fstab/etc/fstab_bak[root@k8s-master01~]#cat/etc/fstab_bak|grep-vswap>/etc/fstab添加k8s源 安装必要的一些系统工具 [root@k8s-master01~]#yuminstall-yyum-utilsdevice-mapper-persistent-datalvm2安装docker [root@k8s-master01~]#systemctlenabledocker\>&&systemctlrestartdocker\>&&systemctlstatusdocker注:daemon.json详解 安装必备软件 [root@k8s-master01~]#yumlistkubeletkubeadmkubectl--showduplicates|sort-r[root@k8s-master01~]#yuminstall-ykubelet-1.15.1kubeadm-1.15.1kubectl-1.15.1ipvsadmipset##设置kubelet开机自启动,注意:这一步不能直接执行systemctlstartkubelet,会报错,成功初始化完后kubelet会自动起来[root@k8s-master01~]#systemctlenablekubelet#kubectl命令补全[root@k8s-master01~]#source/usr/share/bash-completion/bash_completion[root@k8s-master01~]#source<(kubectlcompletionbash)[root@k8s-master01~]#echo"source<(kubectlcompletionbash)">>~/.bashrc修改初始化配置 #查看所需镜像版本[root@k8s-master01tmp]#kubeadmconfigimageslistk8s.gcr.io/kube-apiserver:v1.15.1k8s.gcr.io/kube-controller-manager:v1.15.1k8s.gcr.io/kube-scheduler:v1.15.1k8s.gcr.io/kube-proxy:v1.15.1k8s.gcr.io/pause:3.1k8s.gcr.io/etcd:3.3.10k8s.gcr.io/coredns:1.3.1#下载所需镜像[root@k8s-master01tmp]#kubeadmconfigimagespull--configkubeadm-init.yaml[config/images]Pulledregistry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.15.1[config/images]Pulledregistry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.15.1[config/images]Pulledregistry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.15.1[config/images]Pulledregistry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.15.1[config/images]Pulledregistry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1[config/images]Pulledregistry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.3.10[config/images]Pulledregistry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.3.1初始化 #kubectl默认会在执行的用户家目录下面的.kube目录下寻找config文件。这里是将在初始化时[kubeconfig]步骤生成的admin.conf拷贝到.kube/config[root@k8s-master01tmp]#mkdir-p$HOME/.kube[root@k8s-master01tmp]#sudocp-i/etc/kubernetes/admin.conf$HOME/.kube/config[root@k8s-master01tmp]#sudochown$(id-u):$(id-g)$HOME/.kube/config查看组件状态 [root@k8s-master01tmp]#kubectlgetcsNAMESTATUSMESSAGEERRORschedulerHealthyokcontroller-managerHealthyoketcd-0Healthy{"health":"true"}[root@k8s-master01tmp]#kubectlgetnodesNAMESTATUSROLESAGEVERSIONk8s-master01NotReadymaster6m23sv1.15.1目前只有一个节点,角色是Master,状态是NotReady,状态是NotReady状态是因为还没有安装网络插件部署其他master 在k8s-node01、k8s-node02、k8s-node03执行,注意没有--experimental-control-plane参数 注意**:token有效期是有限的,如果旧的token过期,可以在master节点上使用kubeadmtokencreate--print-join-command重新创建一条token。 在业务节点上执行下面这条命令 以k8s-node01为例 [root@k8s-master01tmp]#kubectlgetnodesNAMESTATUSROLESAGEVERSIONk8s-master01Readymaster59mv1.15.1k8s-master02Readymaster25mv1.15.1k8s-master03Readymaster22mv1.15.1k8s-node01NotReady [root@k8s-master01~]#ipvsadm-LnIPVirtualServerversion1.2.1(size=4096)ProtLocalAddress:PortSchedulerFlags->RemoteAddress:PortForwardWeightActiveConnInActConnTCP10.0.0.1:443rr->20.0.0.201:6443Masq100->20.0.0.202:6443Masq100->20.0.0.203:6443Masq100TCP10.0.0.10:53rr->10.0.122.129:53Masq100->10.0.195.0:53Masq100TCP10.0.0.10:9153rr->10.0.122.129:9153Masq100->10.0.195.0:9153Masq100UDP10.0.0.10:53rr->10.0.122.129:53Masq100->10.0.195.0:53Masq100查看集群状态 dockerpullgcr.azk8s.cn/google_containers/ [root@k8s-master01~]#mkdir/data/tmp/dashboard[root@k8s-master01~]#cd/data/tmp/dashboard[root@k8s-master01dashboard]#ll总用量16-rw-r--r--1rootroot8447月2716:10admin-user-sa-rbac.yaml-rw-r--r--1rootroot51987月2716:13kubernetes-dashboard.yaml-rw-r--r--1rootroot27107月2716:12read-user-sa-rbac.yaml部署dashboard主yaml配置文件 #修改镜像下载地址image:gcr.azk8s.cn/google_containers/kubernetes-dashboard-amd64:v1.10.1[root@k8s-master01dashboard]#kubectlapply-fkubernetes-dashboard.yamlsecret/kubernetes-dashboard-certscreatedserviceaccount/kubernetes-dashboardcreatedrole.rbac.authorization.k8s.io/kubernetes-dashboard-minimalcreatedrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard-minimalcreateddeployment.apps/kubernetes-dashboardcreatedservice/kubernetes-dashboardcreated创建可读可写adminServiceAccount [root@k8s-master01dashboard]#kubectlapply-fadmin-user-sa-rbac.yamlserviceaccount/admin-usercreatedclusterrolebinding.rbac.authorization.k8s.io/admin-usercreated创建只读readServiceAccount [root@k8s-master01dashboard]#kubectlapply-fread-user-sa-rbac.yamlserviceaccount/dashboard-read-usercreatedclusterrolebinding.rbac.authorization.k8s.io/dashboard-read-bindingcreatedclusterrole.rbac.authorization.k8s.io/dashboard-read-clusterrolecreated查看 供本地google浏览器使用#生成client-certificate-data[root@k8s-master01dashboard]#grep'client-certificate-data'~/.kube/config|head-n1|awk'{print$2}'|base64-d>>kubecfg.crt#生成client-key-data[root@k8s-master01dashboard]#grep'client-key-data'~/.kube/config|head-n1|awk'{print$2}'|base64-d>>kubecfg.key#生成p12[root@k8s-master01dashboard]#opensslpkcs12-export-clcerts-inkeykubecfg.key-inkubecfg.crt-outkubecfg.p12-name"kubernetes-client"EnterExportPassword:1Verifying-EnterExportPassword:1[root@k8s-master01dashboard]#ll总用量28-rw-r--r--1rootroot8447月2716:10admin-user-sa-rbac.yaml-rw-r--r--1rootroot10827月2716:23kubecfg.crt-rw-r--r--1rootroot16797月2716:23kubecfg.key-rw-r--r--1rootroot24647月2716:23kubecfg.p12-rw-r--r--1rootroot51987月2716:13kubernetes-dashboard.yaml-rw-r--r--1rootroot27107月2716:12read-user-sa-rbac.yaml[root@k8s-master01dashboard]#szkubecfg.p12谷歌浏览器导入证书:备注把上一步骤的kubecfg.p12文件导入证书后需要重启浏览器: 导出令牌 从Kubernetes1.8开始,资源使用指标(如容器CPU和内存使用率)通过MetricsAPI在Kubernetes中获取,metrics-server替代了heapster。MetricsServer实现了ResourceMetricsAPI,MetricsServer是集群范围资源使用数据的聚合器。MetricsServer从每个节点上的Kubelet公开的SummaryAPI中采集指标信息。 在了解Metrics-Server之前,必须要事先了解下MetricsAPI的概念。MetricsAPI相比于之前的监控采集方式(hepaster)是一种新的思路,官方希望核心指标的监控应该是稳定的,版本可控的,且可以直接被用户访问(例如通过使用kubectltop命令),或由集群中的控制器使用(如HPA),和其他的KubernetesAPIs一样。官方废弃heapster项目,就是为了将核心资源监控作为一等公民对待,即像pod、service那样直接通过api-server或者client直接访问,不再是安装一个hepater来汇聚且由heapster单独管理。 假设每个pod和node我们收集10个指标,从k8s的1.6开始,支持5000节点,每个节点30个pod,假设采集粒度为1分钟一次,则"10x5000x30/60=25000平均每分钟2万多个采集指标"。因为k8s的api-server将所有的数据持久化到了etcd中,显然k8s本身不能处理这种频率的采集,而且这种监控数据变化快且都是临时数据,因此需要有一个组件单独处理他们,k8s版本只存放部分在内存中,于是metric-server的概念诞生了。其实hepaster已经有暴露了api,但是用户和Kubernetes的其他组件必须通过masterproxy的方式才能访问到,且heapster的接口不像api-server一样,有完整的鉴权以及client集成。 有了MetricsServer组件,也采集到了该有的数据,也暴露了api,但因为api要统一,如何将请求到api-server的/apis/metrics请求转发给MetricsServer呢,解决方案就是:kube-aggregator,在k8s的1.7中已经完成,之前MetricsServer一直没有面世,就是耽误在了kube-aggregator这一步。kube-aggregator(聚合api)主要提供:->ProvideanAPIforregisteringAPIservers;->Summarizediscoveryinformationfromalltheservers;->Proxyclientrequeststoindividualservers; MetricAPI的使用:->MetricsAPI只可以查询当前的度量数据,并不保存历史数据->MetricsAPIURI为/apis/metrics.k8s.io/,在k8s.io/metrics维护->必须部署metrics-server才能使用该API,metrics-server通过调用KubeletSummaryAPI获取数据 Metricsserver定时从Kubelet的SummaryAPI(类似/ap1/v1/nodes/nodename/stats/summary)采集指标信息,这些聚合过的数据将存储在内存中,且以metric-api的形式暴露出去。Metricsserver复用了api-server的库来实现自己的功能,比如鉴权、版本等,为了实现将数据存放在内存中吗,去掉了默认的etcd存储,引入了内存存储(即实现Storageinterface)。因为存放在内存中,因此监控数据是没有持久化的,可以通过第三方存储来拓展,这个和heapster是一致的。 KubernetesDashboard还不支持metrics-server,如果使用metrics-server替代Heapster,将无法在dashboard中以图形展示Pod的内存和CPU情况,需要通过Prometheus、Grafana等监控方案来弥补。kuberntes自带插件的manifestsyaml文件使用gcr.io的dockerregistry,国内被墙,需要手动替换为其它registry地址(本文档未替换);可以从微软中国提供的gcr.io免费代理下载被墙的镜像;下面部署命令均在k8s-master01节点上执行。 监控架构 安装metrics-server 这里需要注意: [root@k8s-master011.8+]#kubectlcreate-f.clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-readercreatedclusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegatorcreatedrolebinding.rbac.authorization.k8s.io/metrics-server-auth-readercreatedapiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.iocreatedserviceaccount/metrics-servercreateddeployment.extensions/metrics-servercreatedservice/metrics-servercreatedclusterrole.rbac.authorization.k8s.io/system:metrics-servercreatedclusterrolebinding.rbac.authorization.k8s.io/system:metrics-servercreated查看运行情况 [root@k8s-master011.8+]#kubectl-nkube-systemgetpods-lk8s-app=metrics-serverNAMEREADYSTATUSRESTARTSAGEmetrics-server-6c49c8b6cc-6flx61/1Running059s[root@k8s-master011.8+]#kubectlgetsvc-nkube-systemmetrics-serverNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEmetrics-serverClusterIP10.0.94.102 [root@k8s-master011.8+]#kubectltopnodeerror:metricsnotavailableyet说明还未成功,需要等待一会[root@k8s-master011.8+]#kubectltopnodesNAMECPU(cores)CPU%MEMORY(bytes)MEMORY%k8s-master01292m7%1209Mi64%k8s-master02291m7%1066Mi56%k8s-master03336m8%1212Mi64%k8s-node01125m3%448Mi23%k8s-node02117m2%425Mi22%k8s-node03118m2%464Mi24%[root@k8s-master011.8+]#kubectltoppods-nkube-systemNAMECPU(cores)MEMORY(bytes)calico-kube-controllers-7c4d64d599-w24xk2m14Micalico-node-9hzdk48m40Micalico-node-w75b843m71Micoredns-6967fb4995-ztrlt5m14Mietcd-k8s-master0181m109Mietcd-k8s-master0354m90Mikube-apiserver-k8s-master0153m368Mikube-apiserver-k8s-master0342m331Mikube-controller-manager-k8s-master0132m65Mikube-controller-manager-k8s-master031m16Mikube-proxy-dtpvd1m32Mikube-proxy-lscgw2m20Mikube-scheduler-k8s-master012m28Mikube-scheduler-k8s-master033m18Mi浏览器访问 上面已经部署了metric-server,几乎容器运行的大多数指标数据都能采集到了,但是下面这种情况的指标数据的采集却无能为力:->调度了多少个replicas?现在可用的有几个?->多少个Pod是running/stopped/terminated状态?->Pod重启了多少次?->当前有多少job在运行中? kube-state-metrics指标类别包括: CronJobMetricsDaemonSetMetricsDeploymentMetricsJobMetricsLimitRangeMetricsNodeMetricsPersistentVolumeMetricsPersistentVolumeClaimMetricsPodMetricsPodDisruptionBudgetMetricsReplicaSetMetricsReplicationControllerMetricsResourceQuotaMetricsServiceMetricsStatefulSetMetricsNamespaceMetricsHorizontalPodAutoscalerMetricsEndpointMetricsSecretMetricsConfigMapMetrics以pod为例的指标有: kube-state-metrics优化点和问题1)因为kube-state-metrics是监听资源的add、delete、update事件,那么在kube-state-metrics部署之前已经运行的资源的数据是不是就拿不到了?其实kube-state-metric利用client-go可以初始化所有已经存在的资源对象,确保没有任何遗漏;2)kube-state-metrics当前不会输出metadata信息(如help和description);3)缓存实现是基于golang的map,解决并发读问题当期是用了一个简单的互斥锁,应该可以解决问题,后续会考虑golang的sync.Map安全map;4)kube-state-metrics通过比较resourceversion来保证event的顺序;5)kube-state-metrics并不保证包含所有资源; 配置文件 [root@k8s-master01kubernetes]#ll总用量20-rw-r--r--1rootroot3627月2708:59kube-state-metrics-cluster-role-binding.yaml-rw-r--r--1rootroot12697月2708:59kube-state-metrics-cluster-role.yaml-rw-r--r--1rootroot8007月2720:12kube-state-metrics-deployment.yaml-rw-r--r--1rootroot987月2708:59kube-state-metrics-service-account.yaml-rw-r--r--1rootroot4217月2720:13kube-state-metrics-service.yaml更改配置 [root@k8s-master01kubernetes]#fgrep-R"image"./*./kube-state-metrics-deployment.yaml:image:quay.io/coreos/kube-state-metrics:v1.7.1[root@k8s-master01kubernetes]#catkube-state-metrics-deployment.yaml......image:gcr.azk8s.cn/google_containers/kube-state-metrics:v1.7.1imagePullPolicy:IfNotPresent[root@k8s-master01kubernetes]#catkube-state-metrics-service.yaml......type:NodePortselector:k8s-app:kube-state-metrics执行并检查 至此kubernetes集群部署完成 建议:init6-->验证-->快照 集群部署这块我是思考了又思考的,上次写了114页直接又毁了。这是一个开始,影响后面的学习。我希望自己可以写的更好!