安装配置Kubernetes 最新版1.6.1
资源
- https://github.com/kubernetes... github官方资源
- https://github.com/kubernetes... 最佳实践范例
- https://www.kubernetes.org.cn... 中文社区
- https://github.com/kubernetes... UI管理界面
- https://github.com/google/cad... cAdvisor监控
- https://github.com/rootsongjc... 安装实例指导
- https://kubernetes.io/ 官网
特性
- 分布式集群智能负载均衡、故障发现和自我修复、服务滚动升级、服务注册发现、资源自动调度
- 服务监控、无侵入性。
- 大部分都可以通过Kubectl工具进行增删改查。并保存在etcd库。
- 通过对比etcd库中期望状态和实际资源状态的差异实现自动控制
- 开发,测试,生产环境保持高度一致
- 持续开发,持续集成以及持续部署
- 使用etcd v3版本,因此可支持的集群规模也扩大至5,000个节点,可支持的Pod规模也增加到15万个
- 基于角色的访问控制(RBAC)升级到Beta版
- kubeadm的集群引导工具升级到了Beta版,亮点:所有的通信都通过TLS进行
- 可以通过滚动升级来更新DaemonSet
- API 响应性:99% 的 API 调用应该在一秒之内返回。
- Pod 启动时间:99% 的 Pod 及其容器(已拉取镜像)在五秒之内完成启动。
- 数据格式切换为 protobuf
- v1.6 支持配置不超过2000个节点、不超过6万个pod、不超过12万个集装箱、每个节点不超过100个pod
概念
- Node 节点: 物理机或公有云上的主机,运行Pod
-
Master节点:集群控制节点,运行
- kube-apiserver 提供Rest接口。所有资源的操作唯一入口
- kube-controller-manager 所有资源的自动化控制中心
- kube-scheduler 所有资源调度中心,调度Pod
- etcd库 保存资源
-
Work节点:工作Node节点,运行
- kubelet 负责Pod对应容器的创建,启动停止。向Master注册自己并定时汇报本机信息
- kube-proxy 实现通信和负载均衡
- Docker docker引擎
-
Pod : 运行多个容器,里面所有容器都是与一个业务紧密相关的,组合成一个微服务
- pause 根容器:运行在Pod里,一个Pod一个,代理通信和挂载数据卷,代表Pod的所有容器的状态
- Pod的里容器共享Pause容器的IP,共享Pause容器挂载的存储卷,相互之间文件共享
- 每个Pod都有唯一IP。一个Pod里的容器与另外主机上的Pod容器能直接通讯
- pod中多个容器中应用程序相互访问可以使用localhost就可以
- Pod中根容器停止,将重启Pod即里面所有的容器。
- Pod所在node节点宕机,将会被调度到其他Node节点中启动
-
Pod能限制容器使用的服务器资源CPU和内存
- cpu资源,是一个绝对值,和服务器总cpu个数无关
- 以千分之一的配额为最小单位用m表示,通常一个容器的cpu资源被定义为100-300m即0.1-0.3个cpu
- 内存资源,也是一个绝对值,和服务器总内存数无关,单位可以是Mi 多少兆
- requests: 最小申请值满足容器启动
- limits: 最大使用值,限制容器使用量,超过将会被杀死进程并重启
- pod中容器中的主程序必须在前台执行,不能在后台执行。创建的Docker镜像必须以一个前台命令作为启动命令。
- 如果是无法改为前台执行的程序,可以使用supervisor辅助,其自身会在前台执行
-
ConfigMap:容器应用的配置管理
- 将容器中程序的配置单独出来管理。通过环境变量或外挂载文件的方式在容器创建时注入
- 生成为容器内的环境变量。设置成容器启动命令的启动参数。挂载为容器内部的文件目录
- ConfigMap必须在pod创建之前创建。也可以定义命名空间,只有同一空间中的pod可以引用
-
使用配置的变量:通过环境变量获取ConfigMap中的内容
apiVersion:v1 kind: ConfigMap metadata: name: cm-appvars data: #环境变量形式 apploglevel:info appdatadir:/var/data --- apiVersion:v1 kind: Pod metadata: name: cm-appvars-pod spec: containers: - name: cm-test image: busybox command:["/bin/sh","-c","env |grep APP"] env: #环境变量列表 - name: APPLOGLEVEL #定义环境变量名 valueFrom: #值内容从ConfigMap中获取 configMapKeyRef: #ConfigMap配置 name: cm-appvars #环境变量的值取自cm-appvars中
....
```
-
Pod生命周期和状态:
- Pending已经创建Pod,但pod内还有容器的镜像没有创建
- Runing Pod内所有容器都已经创建,并有一个容器在运行
- Succedded Pod内所有容器都已经退出,并不会重启
- Failed Pod内所有容器都已经退出,并有一个容器退出失败
- Unknown 未知原因无法获取Pod状态,可以是网络原因
- 失效容器重启时间间隔以sync-frequency的2倍计算,重启成功10分钟之后重置时间
-
Pod健康检查:livenessProbe探针判断容器是否存活
- 探测方式:Exec:在容器内部执行一个命令,命令返回码为0,表明健康
- TcpSocket:通过容器IP和端口执行TCP检查,能建立连接表明健康
- HttpGet: 通过容器IP和端口及路径调用get方法,响应状态码大于200小于400则健康
-
Pod调度:将Pod分派到哪个Node中创建。
- 定向调度:指定标签的Node中创建,先将Node打标签kubectl label nodes node名 标签key=标签value。再在Pod配置中的nodeSelector: 标签key:标签value
-
DaemonSet:特定场景调度,在每一个node中创建一个pod副本
- 如每个node上创建一个存储的,日志采集的,性能健康监控采集的、负载均衡、网关入口
- 只需要在Deployment的配置文件中将kind:Deployment改为kind:DaemonSet即可,定义的Pod将在每一个node中创建
-
Pod自动扩容缩容:可以手动命令形式配置,也可以使用HPA配置文件控制
- 命令:kubectl autoscale rc php-apache --min=1 --max=10 --cpu-percent=90
- 表示在1-10之间调整pod副本数量,使平均cpu使用率维持在50%。需要heapster组件
- HPA配置脚本,通过CPU使用率判断是否扩容,需要Pod定义CPU资源限制Request值
- 查看扩容缩容 kubectl get hpa 查看自动扩容详情 kubectl describe hpa
-
只能自动扩容缩容Deployment,ReplicaSet或ReplicationController资源配置kind值
apiVersion: autoscalingv1 kind: HorizontalPodAutoscaler metadata: name: php-apache namespace: default spec: scaleTargetRef: apiVersion: v1 kind: ReplicationController name: php-appache minReplicas: 1 maxReplicas: 10 targetCPUUtilizationPercentage:90
-
Pod滚动升级:将创建一个新的RC,然后控制就的RC中的pod副本数量遂渐减少到0,同时新的RC中的pod副本的数量遂渐增加到目标值。要求新旧RC在同一命名空间中
- kubectl rolling-update 旧rc名 -f 新rc的yml配置文件
- 新rc配置文件中name不能和旧的RC名字相同,可以加版本号前缀区别
- 在配置文件中所有selector选择器中至少有一个label标签和旧的RC中的Label不同,用来标识新RC 如添加版本标签 version: v2
- 最后修改使用升级后的新版本镜像,即可实现升级
- 或不使用配置文件使用新镜像名 kubectl rolling-update 旧rc名 --image=redis-master:2.0
- 如果发现更新过程中发现配置错误,使用回滚命令,回到指定镜像
- kubectl rolling-update 旧rc名 --image=redis-master:1.0 --rollback
-
DaemonSet的滚动更新https://kubernetes.io/docs/ta...
必须将其设置 .spec.updateStrategy.type为RollingUpdate 检查值,结果应该是RollingUpdate kubectl get ds/<daemonset-name> -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}' 或者在创建DaemonSet控制器文件时指定,或者在UI管理界面中修改更新控制器文件 使用更改后的配置文件使修改生效 kubectl apply -f ds.yaml 查看滚动更新状态 kubectl rollout status ds/<daemonset-name> 结果应该是 daemon set "<daemonset-name>" successfully rolled out
- replication controller滚动更新
-
https://kubernetes.io/docs/ta...
#仅更新镜像 kubectl rolling-update 副本控制器名 --image=nginx:1.9.1 #回退之前版本 kubectl rolling-update my-nginx --rollback #使用一个新的配置文件更新 kubectl rolling-update 副本控制器名 -f 配置文件名 配置文件必须选择 metadata.name 新的名字标签使用新标签
- 每个资源都有事件Event,记录事件的各种信息,可以帮助排查故障
-
Label标签:可以附加在各种资源上,如Pod、Node、Service、RC等,一个资源对象可以定义任意数量的多个标签,同一个标签也可以添加到任意数量的多个资源上。用来实现管理,使用标签筛选器查找。常用标签:
- 版本标签:release:alpha初始版、release:beta测试版、release:stable稳定版
- 环境标签:environment:dev开发、environment:production生产、environment:test测试
- 架构标签:role:frontend前端、role:backend后端、role:middleware中间
-
Replication Controller(RC)副本控制器:定义资源预期期望的环境,声明pod副本的数量在任意时刻都符合某个预期值。调度管理pod
- 定义了 Pod 期待的副本数量
- 用户筛选pod的 Lable selector标签选择器
- 包含了 创建新pod的pod定义模板
- 可以动态修改pod数量实现自动扩容或缩容 kubectl scale rc php-slave --replicas=3
- 删除RC并不会删除已经通过此RC创建的Pod,删除全部Pod 可以使用stop和delete命令
- 滚动升级,就是通过RC的控制,改变Pod模板中的镜像版本,停掉旧的Pod启动新的Pod
-
Replica Set 下一代的RC。区别是支持集合的标签选择器,RC只支持等于的选择器
apiVersion: v1 kind: ReplicaSet metadata: name: mysql spec: selector: matchLabels: tier: mysql matchExpressions:
....
```
- Replica Set 被Deployment资源使用。两者替换了RC的作用
-
Deployment :调度部署是新概念。内部使用RC的升级版Replica Set实现调度目的。
- 可以随时知道当前Pod部署的进度,查看部署状态数量等信息。
- 可以修改镜像更新Deployment,创建新的Pod
- 如果当前Deployment 不稳定,可以回滚之前的版本
- 同样可以通过kubectl get rc 查看副本控制信息
- 同样可以通过kubectl get pods 查看pod的创建信息
-
创建的Pod资源命名规则会以Deployment对应的Replica Set的名字为前缀
apiVersion: v1 kind: Deployment metadata: name: nginx-Deployment ....
-
Service 服务:定义一个服务的访问入口地址,前端应用如php的Pod通过这个入口地址,访问背后的一组由Pod副本集群组成提供的服务。服务与集群之间通过标签选择器定位,RC副本控制器保证集群处于预期状态。
- 服务对外开启访问端口
- 服务提供负载均衡,负载同一服务的不同Pod
- 服务提供全局唯一虚拟IP即Cluster IP,服务生存期内IP不会改变。无法被ping。结合Service Port组合成一个具体的通信端口,单独的一个不具备TCP/IP通信基础。属于集群内部地址,外部无法访问。外部方法可以设置节点映射端口
- 服务提供全局唯一的名字
- 服务发现通过service的Name和Cluster IP做一个DNS域名映射解决
- DNS系统支持服务发现,使用服务名作为DNS域名。
- 服务支持多端口通过端口名字区分
- Pod本身是变化的,比如当Pod发生迁移,那么Pod的IP是变化的, 那么Service的就是在Pod之间起到中转和代理的作用,Service会生成一个虚拟IP, 这个虚拟IP负载均衡到后端的Pod的IP
- iptables-save 查看iptables重定向
- 服务处在多节点服务器上的负载均衡需要一个单独的负载均衡设备,这个不属于Kubernetes
-
只要部署了service 那么无论是使用哪种方式访问服务(访问服务IP也好服务域名也好,宿主机端口也好),都会被负载均衡调度,除非只有一个pod。因为发送到node上指定端口的数据,会通过iptables重定向到kube-proxy对应的端口上。然后由kube-proxy进一步把数据负载均衡发送到其中的一个pod上。
apiVersion: v1 kind: Service metadata: name: mysql-service spec: selector: tier: mysql type: NodePort #使用节点端口开放服务 ports: #多服务端口支持 - port: 3600 name: service-port nodePort: 3600 #开放的节点端口,外部使用节点IP和此端口可以访问此服务 - port: 3601
....
```
-
Volume:存储卷。挂载在Pod中,提供给Pod中所有容器共享访问的目录。
- 生命周期和Pod的相同和容器无关,容器的重启终止不会影响。
-
数据卷类型:
- emptyDir:临时的,初始内容为空,不需要指定宿主机对应的目录。Pod被从Node删除时,数据卷数据也被删除。存储应用程序的临时数据。
- hostPath:挂载在宿主机上的文件或目录。容器应用程序生产的日志文件等,注意不同Node的目录文件不一致
- Persistent Volume:PV网络云存储。不属于任何Node,但可以在任何Node上访问。独立于Pod
- https://github.com/kubeup/kub... 阿里云支持存储卷但不支持PVC
- 网络存储PV 类型:NFS(网络文件系统NAS)、iSCSCI(降级SAN存储区域网络企业级存储)、GlusterFS、ceph
- 阿里云内网速度是共享千兆网卡 1Gbps 速率
-
定义在Pod的配置中
apiVersion: v1 #版本号 kind: Pod # kind定义这个一个pod资源 metadata: name: myweb #定义pod名字 labels: #定义标签 name:myweb spec: #定义pod里容器属性 volumes: #定义数据卷的类型和名字 - name: datavo1 emptyDir: {} - name: storage hostPath:
containers:
- name: myweb #定义容器名
image: kuberguide/tomcat-app:v1 #定义容器使用镜像
volumeMounts: #挂载在pod的位置
- mountPath: /mydata-data
name: datavo1
.....
```
-
Namespace:命名空间,支持多租户,实现资源隔离。默认空间是default。不指名空间所有资源pod、RC、Service都会被创建到默认命名空间,查询命令不加参数都查询的是默认空间中的对象数据。
- kubectl get pods --namespace=developemnt 指定命名空间查询
- 不同项目组不同空间,或者不同环境不同空间,如紫色医疗和嘟嘟医生,或开发环境、测试环境、正式环境
-
可以隔离不同空间下不同租户使用资源如:cpu、内存
apiVersion: v1 #版本号 kind: Namespace metadata: name: developemnt # ... #使用 apiVersion: v1 #版本号 kind: Pod metadata: name: myweb namespace: developemnt #指定pod创建在哪个租户下 ....
-
secret 秘钥账号密码资源
#创建一个ssh秘钥的资源 kubectl create secret generic nginx-php-ssh-key --from-file=id_rsa=/home/kube_yaml/nginx_php/id_rsa --from-file=id_rsa.pub=/home/kube_yaml/nginx_php/id_rsa.pub #使用:挂载使用时 id_rsa和id_rsa.pub 这两个键名会作为挂载目录下的文件名 ,健值会作为文件对应的内容 volumeMounts: - name: ssh-key mountPath: "/root/.ssh"
#环境变量中使用
env:
- name: id_rsa
valueFrom:
secretKeyRef:
name: nginx-php-ssh-key
key: id_rsa.pub
volumes:
- name: ssh-key
secret:
secretName: nginx-php-ssh-key
-
Dashboard UI 图形化界面 1.4版本
- https://github.com/kubernetes... 地址
- kubectl create -f https://rawgit.com/kubernetes... 安装最新版
- 需要安装 Heapster 支持
- 执行kubectl proxy 启动代理 访问 http://localhost:8001/ui
- 只能在执行命令的主机上访问,可以通过apiserver的代理访问。http://Master服务器ip/ui 需要设置apiserver支持用户名账号方式访问
- kubeadm init和kubeadm join 简化安装部署 1.4版本
-
service account 服务账号并不是给集群的用户使用的,而是给运行在pod里的进程使用的,为pod里的进程提供必要的身份证明
- 为确保集群安全,api server会对客户端进行身份认证,认证失败无法调用api。pod中访问api server服务时是以service方式访问服务名为kubernetes的服务的。这个服务只在https 443端口上提供服务,使用的是一种http token的认证方式
- 每个namespace 命名空间下都有个名为default的默认service account对象,这个对象里有个名为tokens的可以当做volume一样被挂载到pod里的secret秘钥,当pod启动时,这个secret会被自动挂载到pod的指定目录下,来协助pod中的进程完成访问api server的身份验证过程 kubectl describe serviceaccounts 再查看详情 kubectl describe secrets default-token-xxxx
- 如果一个pod在创建时没有定义spec.serviceAccountName属性,系统会自动设置为default,即大家都是用同一个namespace命名空间下默认的service account服务账号
- service account 服务账号是属于某个具体的Namespace空间的
- 如果一个Namespace下没有默认的service account账号将会为该空间创建一个default默认的setvice account
- 在kube-apiserver 启动参数中 --admission_control=ServiceAccount准入控制器时,将会验证pod里的service accont是否合法
- 如果pod的spec.serviceAccountName指定了default以外的service account 而该service account没有事先被创建,则该pod将无法创建
-
创建一个service account
- openssl genrsa -out /tmp/kube-serviceaccount.key 2048 首先生成key
- kube-apiserver ... --service_account_key_file=/tmp/kube-serviceaccount.key 启动参数中添加key
- kube-apiserver --admission_control=...,ServiceAccount 并且API Server设置admission_control包含ServiceAccount
- kube-controller-manager ... --service_account_private_key_file=/tmp/kube-serviceaccount.key... 启动Controller Manager增加service_account_private_key_file
- kubectl get serviceaccount --all-namespaces 查看每个namespace都会默认创建的一个ServiceAccount
- 可以创建一个服务账号
serviceaccount.yaml apiVersion: v1 kind: ServiceAccount metadata: name: build-robot namespace: kube-system #不指定命名空间则为default默认命名空间
- kubectl create -f serviceaccount.yaml 创建
- kubectl get serviceaccounts/build-robot -o yaml 查看ServiceAccount默认创建一个secret,也可以手动创建secret然后添加到ServiceAccount。
- secrets: - name: build-robot-token-3uazg
- 创建Pod使用ServiceAccount
busybox-pod.yaml: apiVersion: v1 kind: Pod metadata: name: busybox spec: containers: - image: busybox command: - sleep - "3600" imagePullPolicy: IfNotPresent name: busybox serviceAccountName: build-robot #指定使用的非默认default的服务账号
- Pod创建成功后,可以查询Pod的容器挂载/var/run/secrets/kubernetes.io/serviceaccount位置保存
"Volumes": { "/var/run/secrets/kubernetes.io/serviceaccount": "/var/lib/kubelet/pods/05174b7d-426d-11e5-aacb-005056817c3e/volumes/kubernetes.io~secret/build-robot-token-3uazg" },
- kubectl exec busybox cat /var/run/secrets/kubernetes.io/serviceaccount/token 查看token。实际上这个目录是ServiceAccount的Secret,里面包含了一个token,应用通过使用这个token便可以去访问
安装
- 升级:遂各隔离Node,等待上面容器执行完成,再更新Node上的kubelet、kube-proxy。全部更新完node之后,更新Master上的服务
-
单机本地Minikube安装
- https://github.com/kubernetes... 代码地址安装说明
- 支持DNS、NodePorts、ConfigMaps、Secrets、Dashboards、Ingress
-
MacOS安装要求: VirtualBox虚拟机 和kubectl命令行工具
- brew install kubectl 安装命令行脚本
- kubectl version 检查版本号
- brew install bash-completion 安装命令行自动完成支持,节约敲命令
- 当前shell生效
- source $(brew --prefix)/etc/bash_completion
- source <(kubectl completion bash)
- 加入环境
- echo "source $(brew --prefix)/etc/bash_completion" >> ~/.bash_profile
- echo "source <(kubectl completion bash)" >> ~/.bash_profile
-
开始安装Minikube
- curl -Lo minikube https://storage.googleapis.co... && chmod +x minikube && sudo mv minikube /usr/local/bin/
- 无法下载可以从官网地址直接下载再安装
- https://github.com/kubernetes... 下载地址
- sudo mv minikube-darwin-amd64 /usr/local/bin/minikube 移动加改名
- chmod +x minikube 执行权限
- minikube start 启动
- kubectl cluster-info 检查集群是否准备好
- eval $(minikube docker-env) #连接集群中的docker,未连接的shell会话无法操作集群中的docker
- docker ps #之后就可以获得运行的docker数据
- minikube stop 停止集群 保留集群状态和数据,重启将恢复
- minikube delete 删除集群
- 安装仪表盘
- 由于使用的镜像是在谷歌服务器所以国内访问不到,可以使用阿里云镜像
- docker pull registry.cn-hangzhou.aliyuncs.com/kube_containers/kubernetes-dashboard-amd64
- 再修改 kubernetes-dashboard.yaml 中的镜像来源配置
- kubectl create -f https://rawgit.com/kubernetes...
- minikube dashboard 获取web UI 地址
- minikube service [-n NAMESPACE] [--url] NAME 获取集群中开放端口的服务访问地址
- minikube ip 获取集群服务IP地址,任何开放的服务都可以通过该地址和端口号访问
- kubectl get service 服务名 --output='jsonpath="{.spec.ports[0].nodePort}"' 获取集群中服务的访问端口号
- 之后可以按照一般创建pod以及service的步骤去创建服务了
- 查看服务需要使用命名空间参数kubectl get service kubernetes-dashboard --namespace=kube-system 删除和查询详情都是需要指定命名空间
- kubectl describe pod kubernetes-dashboard --namespace=kube-system
- 注意gcr.io/google_containers/pause-amd64:3.0 pod的基础容器pause也是在谷歌上
-
临时解决方法:
https://github.com/kingtongxingsheng/docker-library https://hub.docker.com/r/carrotking/kubernetes/~/settings/automated-builds/ 在我的dockerhub上的kubernetes项目中自动构建对应镜像 执行 minikube ssh 命令登录到minikube节点中或eval $(minikube docker-env) 拉取镜像到本地仓库中 docker pull carrotking/kubernetes:pause_amd64_3.0 重新tag: docker tag image_id gcr.io/google_containers/pause-amd64:3.0 之后就能正常启动这个test pod了
- kubeadm 安装
-
完全手动遂一安装 官方参考文档https://kubernetes.io/docs/ge...
-
基础依赖管理配置:
- 多主机网络连通管理,使用flannel。每个Node节点的子网规划a/24可以配置254个pod,如果一个主机上不需要启动那么多pod也可以a/25 128个pod,a/26 62个pod,a/27 30个pod
- 192.168.0.0/16 作为node节点的IP范围,那么可以有192.168.0.0/24 - 192.168.255.0/24 个node节点主机
- 集群服务也需要IP,设置SERVICE_CLUSTER_IP_RANGE="192.168.0.0/16" 将有 65534 个服务可以同时存在,一个节点254个ip服务占据1/3 ip,pod占据2/3 ip
- 主节点:需要设置静态IP MASTER_IP;打开任何防火墙以允许访问apiserver端口80和443;启用ipv4转发sysctl, net.ipv4.ip_forward = 1
- 集群命名:CLUSTER_NAME 可以区分测试,开发,不同部门的环境,第三方,互不影响
- 下载二进制包etcd数据库、docker、kubelet命令、kube-proxy网络代理、kube-apiserver接口服务、kub-controller-manager容器管理、kub-scheduler调度
- DNS 服务
- CA证书 在阿里内网环境可以不用证书验证,使用阿里安全组功能屏蔽外网访问
- NFS 网络数据存储服务
- flannel 使用 0.7.0 docker pull registry.cn-hangzhou.aliyuncs.com/gcr-io/flannel:v0.7.0-amd64
- Etcd 版本使用Kubernetes二进制分发中提供的etcd版本,目前最新是3.0.17,经过了广泛测试 docker pull registry.cn-shenzhen.aliyuncs.com/gcrio/etcd-amd64:3.0.17
- 关闭防火墙 systemctl status firewalld systemctl disable firewalld systemctl stop firewalld
- Master安装etcd服务
-
Master安装kube-apiserver、kub-controller-manager、kub-scheduler 作为容器运行 docker pull registry.cn-hangzhou.aliyuncs.com/google-containers/hyperkube-amd64:1.6.1-f50fbf0
wget https://github.com/kubernetes/kubernetes/releases/download/v1.6.1/kubernetes.tar.gz tar xzvf kubernetes.tar.gz && cd kubernetes && ./cluster/get-kube-binaries.sh 下载server和client的可执行文件 #执行该shell会自动下载kube的server和client可执行文件,其中客户端文件会自动安装在kubernetes目录下的client文件夹下,只需将bin添加到PATH下就可以了 cd server &&tar xzvf kubernetes-server-linux-amd64.tar.gz #查看目录下文件 ll kubernetes/server/bin cd kubernetes/server/bin cp -r server/bin/{kube-apiserver,kube-controller-manager,kube-scheduler,kubectl,kube-proxy,kubelet} /usr/local/bin/ #编辑配置kubeconfig server 地址为本机当中安装的apiserver地址 vim /etc/kubernetes/kubeconfig current-context: kube-context apiVersion: v1 kind: Config users: - name: controllermanager user: client-certificate: /root/ssl/apiserver.pem
-
clusters:
- name: kubernetes
cluster:
certificate-authority: /root/ssl/ca.pem
server: https://10.29.167.233:6443
contexts:
- context:
cluster: kubernetes
user: controllermanager
name: kube-context
#编辑公共配置文件主从都有
mkdir -p /etc/kubernetes
vim /etc/kubernetes/config
###
# kubernetes system config
#
# The following values are used to configure various aspects of all
# kubernetes services, including
#
# kube-apiserver.service
# kube-controller-manager.service
# kube-scheduler.service
# kubelet.service
# kube-proxy.service
# 为true 日志输出到屏幕 false 日志写入文件
KUBE_LOGTOSTDERR="--logtostderr=false"
#日志保存目录 日志目录主从都要先创建好才能启动服务
KUBE_LOG_DIR="--log-dir=/var/log/k8s"
# 日志等级 0 is debug 2
KUBE_LOG_LEVEL="--v=2"
# 是否允许允许系统特权容器Pod
KUBE_ALLOW_PRIV="--allow-privileged=true"
# How the controller-manager, scheduler, and proxy find the apiserver
# master使用本机安装的apiserver地址
KUBE_MASTER="--master=https://10.29.167.233:6443"
查看端口占用netstat -anp |grep 6443
#编辑apiserver配置文件
vim /etc/kubernetes/apiserver
###
## kubernetes system config
##
## The following values are used to configure the kube-apiserver
##
#
## 绑定非安全认证访问地址 insecure-bind-address默认0.0.0.0全部网络,可以允许外部访问,如果放置在负载均衡后面可以绑定本机IP
KUBE_API_ADDRESS="--advertise-address=10.29.167.233 --bind-address=0.0.0.0"
#
## 非安全认证访问监听端口默认8080 ,安全组中配置外部客户端不可访问
KUBE_API_PORT="--insecure-port=0"
#
## etcd 集群
KUBE_ETCD_SERVERS="--etcd-servers=http://10.29.167.233:2379,http://10.29.167.233:2377,http://10.29.167.233:2378"
#
## 服务虚拟IP地址池,不能和物理机所在网络重合如169.169.0.0
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=169.169.0.0/16"
#
## 默认允许控制政策,对发送给API Server的任何请求进行拦截和过滤
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota"
#
## Add your own! secure-port=0不启用https默认6443
KUBE_API_ARGS="--cloud-provider='' --enable-garbage-collector=true --secure-port=6443 --service-node-port-range=30000-32767 --apiserver-count=1 --client-ca-file=/home/sharefiles/ssl/ca.pem --tls-cert-file=/home/sharefiles/ssl/kubernetes.pem --tls-private-key-file=/home/sharefiles/ssl/kubernetes-key.pem
--service-account-key-file=/home/sharefiles/ssl/kubernetes-key.pem --etcd-prefix=kubernetes"
#安装kube-apiserver服务
#编辑系统启动服务配置
vim /usr/lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Service
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
EnvironmentFile=/etc/kubernetes/config
EnvironmentFile=/etc/kubernetes/apiserver
ExecStart=/usr/local/bin/kube-apiserver \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_LOG_DIR \
$KUBE_ETCD_SERVERS \
$KUBE_API_ADDRESS \
$KUBE_API_PORT \
$KUBE_ALLOW_PRIV \
$KUBE_SERVICE_ADDRESSES \
$KUBE_ADMISSION_CONTROL \
$KUBE_API_ARGS
Restart=on-failure
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
#启动服务
systemctl daemon-reload
systemctl enable kube-apiserver
systemctl start kube-apiserver
systemctl status -l kube-apiserver
systemctl restart kube-apiserver
systemctl stop kube-apiserver
#安装controller-manager
vim /etc/kubernetes/controller-manager
# cluster-name 集群名 root-ca-file CA根证书
KUBE_CONTROLLER_MANAGER_ARGS="--cloud-provider='' --enable-garbage-collector=true --terminated-pod-gc-threshold=5 --address=127.0.0.1 --service-cluster-ip-range=169.169.0.0/16 --cluster-cidr=172.17.0.0/16 --root-ca-file=/home/sharefiles/ssl/ca.pem --service-account-private-key-file=/home/sharefiles/ssl/kubernetes-key.pem --kubeconfig=/etc/kubernetes/kubeconfig"
vim /usr/lib/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=kube-apiserver.service
Requires=kube-apiserver.service
[Service]
EnvironmentFile=/etc/kubernetes/config
EnvironmentFile=/etc/kubernetes/controller-manager
ExecStart=/usr/local/bin/kube-controller-manager \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_LOG_DIR \
$KUBE_MASTER \
$KUBE_CONTROLLER_MANAGER_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable kube-controller-manager
systemctl start kube-controller-manager
systemctl status -l kube-controller-manager
systemctl restart kube-controller-manager
systemctl stop kube-controller-manager
#安装kube-scheduler
vim /etc/kubernetes/scheduler
KUBE_SCHEDULER_ARGS="--address=127.0.0.1 --kubeconfig=/etc/kubernetes/kubeconfig"
vim /usr/lib/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler Plugin
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=kube-apiserver.service
Requires=kube-apiserver.service
[Service]
EnvironmentFile=/etc/kubernetes/config
EnvironmentFile=/etc/kubernetes/scheduler
ExecStart=/usr/local/bin/kube-scheduler \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_LOG_DIR \
$KUBE_MASTER \
$KUBE_SCHEDULER_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable kube-scheduler
systemctl start kube-scheduler
systemctl status -l kube-scheduler
systemctl restart kube-scheduler
systemctl stop kube-scheduler
#配置kubectl
cd ~/.kube/
vim config
current-context: kube-context
apiVersion: v1
kind: Config
users:
- name: controllermanager
user:
client-certificate: /root/ssl/apiserver.pem
client-key: /root/ssl/apiserver-key.pem
clusters:
- name: kubernetes
cluster:
certificate-authority: /root/ssl/ca.pem
server: https://10.29.167.233:6443
contexts:
- context:
cluster: kubernetes
user: controllermanager
name: kube-context
#或使用命令行配置config
# 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/home/sharefiles/ssl/ca.pem \
--embed-certs=true \
--server=https://10.29.167.233:6443
# 设置客户端认证参数
kubectl config set-credentials controllermanager \
--client-certificate=/home/sharefiles/ssl/apiserver.pem \
--embed-certs=true \
--client-key=/home/sharefiles/ssl/apiserver-key.pem
# 设置上下文参数
kubectl config set-context kube-context \
--cluster=kubernetes \
--user=controllermanager
# 设置默认上下文
kubectl config use-context kube-context
#验证master节点
kubectl --server=https://10.29.167.233:6443 --certificate-authority=/home/sharefiles/ssl/ca.pem \
--client-certificate=/home/sharefiles/ssl/apiserver.pem \
--client-key=/home/sharefiles/ssl/apiserver-key.pem \
get cs
或
kubectl get cs
#node节点安装
创建工作目录
mkdir /var/lib/kubelet
修改主机名centos7
vim /etc/cloud/cloud.cfg将
preserve_hostname=fale 改为
preserve_hostname=true
hostnamectl set-hostname node_246 重新登录即可
yum install conntrack-tools
vim /etc/kubernetes/kubelet
###
## kubernetes kubelet (minion) config
#
## The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
KUBELET_ADDRESS="--address=10.29.168.24"
#
## 本节点在集群中的名字 10.29.167.186
KUBELET_HOSTNAME="--hostname-override=10.29.168.24"
#
## api-server服务地址
KUBELET_API_SERVER="--api-servers=https://10.29.167.233:6443"
#
## pod 基础pause镜像
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.cn-shenzhen.aliyuncs.com/gcrio/pause-amd64:3.0"
#
## Add your own!
#--cluster-dns 指定 kubedns 的 Service IP(可以先分配,后续创建 kubedns 服务时指定该 IP),
#--cluster-domain 指定域名后缀,这两个参数同时指定后才会生效
#--root-dir 运行根目录 保存pod 和 volume 的文件
KUBELET_ARGS="--cloud-provider='' --cluster-dns=169.169.1.1 --root-dir=/var/lib/kubelet --cluster-domain=cluster.local --serialize-image-pulls=false --kubeconfig=/etc/kubernetes/kubeconfig --hairpin-mode=promiscuous-bridge"
vim /usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
EnvironmentFile=/etc/kubernetes/config
EnvironmentFile=/etc/kubernetes/kubelet
ExecStart=/usr/local/bin/kubelet \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_LOG_DIR \
$KUBELET_API_SERVER \
$KUBELET_ADDRESS \
$KUBELET_HOSTNAME \
$KUBE_ALLOW_PRIV \
$KUBELET_POD_INFRA_CONTAINER \
$KUBELET_ARGS
Restart=on-failure
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable kubelet
systemctl start kubelet
systemctl status -l kubelet
systemctl stop kubelet
systemctl restart kubelet
#安装kube-proxy
vim /etc/kubernetes/proxy
#--hostname-override 参数值必须与 kubelet 的值一致
#kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量 pod的地址范围,用于桥接集群外部流量到内部,
#snat IP地址转换,将内网向外网发出的包的内网源地址改成可以被外网访问到的ip地址,方便外网的请求可以请求到内网
KUBE_PROXY_ARGS="--bind-address=10.29.168.24 --hostname-override=10.29.168.24 --cluster-cidr=172.17.0.0/16 --kubeconfig=/etc/kubernetes/kubeconfig"
vim /usr/lib/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
Requires=network.service
[Service]
EnvironmentFile=/etc/kubernetes/config
EnvironmentFile=/etc/kubernetes/proxy
ExecStart=/usr/local/bin/kube-proxy \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_LOG_DIR \
$KUBE_MASTER \
$KUBE_PROXY_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
#启动服务
systemctl daemon-reload
systemctl enable kube-proxy
systemctl start kube-proxy
systemctl status -l kube-proxy
systemctl stop kube-proxy
systemctl restart kube-proxy
#检查节点
kubectl get nodes
#测试
kubectl run nginx --replicas=2 --labels="run=load-balancer-example" --image=nginx:1.11.13 --port=80
kubectl expose deployment nginx --type=NodePort --name=example-service
kubectl describe svc example-service
#访问主节点所有从节点的主机端口都应该能访问到nginx,以及访问pod服务虚拟IP也应该能访问到nginx
curl "121.42.248.198:30101"
```
- Node安装Docker引擎
- Node安装kubelet、kube-proxy
- Master安装私有Docker镜像仓库
- 获取kubeguide/google_containers/pause-amd64:3.0镜像提交到私有仓库,此仓库是创建Pod使用的
- Node配置kubelet启动参数--pod_infra_container_image=kubeguide/google_containers/pause-amd64:3.0使用私有仓库地址为pause镜像地址。
-
集群网络配置。多Node节点网络互通是底层配置,与Kubernetes无关需要自行配置
- flannel 覆盖网络,官方推荐。封装了数据包,会降低性能。需要安装etcd
-
直接路由:性能最好设置简单,就是多台Node节点配置静态路由转发规则较为繁琐,可以使用quagga管理。需要规划每台Node节点docker0网卡子网IP段不能相互冲突重复。重启服务器时,Docker0地址会变化需要设置固定值,阿里云网络不支持路由配置
sudo ifconfig docker0 172.17.0.254/24 master 主机 ifconfig配置重启之后就会还原,需要使用bip绑定ip参数 sudo ifconfig docker0 172.17.1.254/24 /24表示24个1 8个0 表示此子网段可以有256台主机 sudo ifconfig docker0 172.17.2.254/24 254为节点主机Docker0网卡的IP地址。172.17.2.1-253 都是一个子网的 .... 可以一直到172.17.254.254/24 sudo systemctl restart docker #重启 #在主机master 上添加路由 sudo route add -net 172.17.1.0 netmask 255.255.255.0 gw 节点主机1的内网IP sudo route add -net 172.17.2.0 netmask 255.255.255.0 gw 节点主机2的内网IP #在节点主机1上 添加路由 sudo route add -net 172.17.0.0 netmask 255.255.255.0 gw master主机的内网IP sudo route add -net 172.17.2.0 netmask 255.255.255.0 gw 节点主机2的内网IP #不在同一网段 先将网关IP当成一个主机加进来,这样在这两个IP直接建立一个连接,并且不设置掩码,即能到达所有其他网段。 route add -host 202.194.20.254 netmask 0.0.0.0 dev eth0 #然后再将网关IP加成网关 route add default gw 202.194.20.254 netmask 0.0.0.0 dev eth0 #查看路由 route -n #删除路由记录 route del -net 172.17.1.0/24 或 route del -net 172.17.1.0 netmask 255.255.255.0 #删除默认网关记录 route del default gw 192.168.120.240 #跟踪路由跳转 traceroute 172.17.0.1
- 使用Calico 网络插件:插件中性能最好,创建路由表形式,在同一个子网中,通过路由方式转发数据包,无性能损耗,在不同子网中,需要隧道,有性能损耗。但同样阿里云网络不支持路由修改;
- 使用阿里云的vps 专用高速网络:配置一个大的自定义的局域网。用的也是隧道技术覆盖网络
-
DNS服务skydns安装
- 安装etcd
- kube2sky 时刻调取apiserver的API获取集群中所有服务的信息,并将service服务写入etcd
- skyDns 解析DNS域名
- healthz 健康检查
- 将启动四个容器放在一个pod中,
- skydns的pod虚拟clusterIP地址必须是固定的,不能通过系统自动分配需要在server服务配置文件中使用clusterIP:选项配置,并在apiserver的指定ip地址范围。
- 再修改每台Node上kubelet启动参数配置DNS服务的固定IP地址及域名
- 之后通过服务名:端口号即可找到对应服务。不再担心服务重启后IP地址变更的问题
- 每台Node的kubelet服务会去访问DNS服务,得到解析域名之后的对应IP地址再去访问服务
-
1.4版本DNS服务
-
kubedns容器
- 监视k8s Service资源并更新DNS记录
- 替换etcd,使用TreeCache数据结构保存DNS记录并实现SkyDNS的Backend接口
- 接入SkyDNS,对dnsmasq提供DNS查询服务
-
dnsmasq容器
- 对集群提供DNS查询服务
- 设置kubedns为upstream
- 提供DNS缓存,降低kubedns负载,提高性能
-
exechealthz容器
- 定期检查kubedns和dnsmasq的健康状态
- 为k8s活性检测提供HTTP API
-
对比1.2版改进
- 无状态服务。1.2版本中,需要将Etcd的数据Volume出来才能保证Etcd容器重启之后数据不会丢失,服务可以快速恢复。新版本中作为无状态服务出现,通过增加冗余来提高可靠性。即使kubedns容器重启,dnsmasq缓存机制也可以保证服务的可用性。
- 优化查询效率。SkyDNS直接从内存中获取DNS记录。
- 完善健康检查。1.2版本中只对kube2sky设置了健康检查
- 不足,内存占用问题,默认设置了内存限制为170M,大规模集群中使用未验证
-
安装
mkdir -p /home/kube_yaml/kubedns/ cd kubernetes/cluster/addons/dns/ cp kubedns-sa.yaml /home/kube_yaml/kubedns 修改namespace: kube-system cp kubedns-cm.yaml /home/kube_yaml/kubedns 无需修改 ConfigMap cp kubedns-svc.yaml.base /home/kube_yaml/kubedns/kubedns-svc.yaml 替换clusterIP: __PILLAR__DNS__SERVER__ 为 clusterIP: 169.169.1.1 和 kubelet 的 --cluster-dns 参数值一致; cp kubedns-controller.yaml.base /home/kube_yaml/kubedns/kubedns-controller.yaml 修改所有镜像地址为本地私有仓库 dudureg.xip.io:5000/k8s-dns-dnsmasq-nanny-amd64:1.14.1 dudureg.xip.io:5000/k8s-dns-kube-dns-amd64:1.14.1 dudureg.xip.io:5000/k8s-dns-sidecar-amd64:1.14.1 替换所有__PILLAR__DNS__DOMAIN__ 为cluster.local 如:-- domain=cluster.local. 域名 #__PILLAR__FEDERATIONS__DOMAIN__MAP__ 注释 #创建所有资源kubedns-cm.yaml kubedns-controller.yaml kubedns-sa.yaml kubedns-svc.yaml kubectl create -f . #系统预定义的 RoleBinding system:kube-dns 将 kube-system 命名空间的 kube-dns ServiceAccount 与 system:kube-dns Role 绑定, 该 Role 具有访问 kube-apiserver DNS 相关 API 的权限; 查看命令 kubectl get clusterrolebindings system:kube-dns -o yaml kubedns-controller.yaml 中定义的 Pods 时使用了 kubedns-sa.yaml 文件定义的 kube-dns ServiceAccount,所以具有访问 kube-apiserver DNS 相关 API 的权限。 获取有密码账号验证的私有镜像仓库的镜像 Pods只能在其自己的命名空间中引用图像拉取秘密,因此每个命名空间需要执行一次此过程。 kubectl create secret docker-registry regsecret --docker-server=dudureg.ziseyiliao.com:5000 --docker-username=duduyisheng --docker-password=duducode --docker-email=tongxingsheng@ziseyiliao.com 查看 kubectl get secret regsecret --output=yaml 在Pod中使用 imagePullSecrets:
-
也可以不设置私有仓库账号密码
#测试
mkdir -p /home/kube_yaml/test && cd /home/kube_yaml/test
cat << EOF > test-nginx.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: test-nginx
spec:
replicas: 2
template:
metadata:
labels:
run: test-nginx
spec:
containers:
- name: test-nginx
image: dudureg.xip.io:5000/nginx:1.11.13
ports:
- containerPort: 80
EOF
kubectl create -f test-nginx.yaml
kubectl expose deploy test-nginx
kubectl get services --all-namespaces |grep test-nginx
kubectl --namespace=kube-system describe service/kube-dns
#dns组件可以为k8s集群内的service做dns解析
#进入一个pod
docker exec -ti k8s_test-nginx_test-nginx-218109665-j3h5z_default_83630203-28b4-11e7-a447-00163e05ddb0_0 /bin/bash
#查看
cat /etc/resolv.conf
3#ping域名 都不能ping通,但都有对应解析地址就是成功
ping test-nginx
ping kubernetes
ping kube-dns.kube-system.svc.cluster.local
#使用
my-svc.my-namespace.svc.cluster.local A记录服务域名
my-svc 为服务名 my-namespace 为命名空间默认空间为 default。 svc.cluster.local 为域名
pod-ip-address.my-namespace.pod.cluster.local A记录Pod域名
pod-ip-address 为pod的ip地址 my-namespace 为命名空间默认空间为 default。 pod.cluster.local 为pod域名
```
-
安装配置UI
- 官方yaml配置在kubernetes/cluster/addons/dashboard 目录
- dashboard-service.yaml 无修改;
- dashboard-controller.yaml 修改镜像地址image=dudureg.xip.io:5000/kubernetes-dashboard-amd64:v1.6.0
- kubectl get services kubernetes-dashboard -n kube-system 查看服务
- kubectl get deployment kubernetes-dashboard -n kube-system
- kubectl get pods -n kube-system | grep dashboard
- 访问方式 IP加端口号;kube-apiserver 接口访问;代理访问kubectl proxy
- kubectl proxy --address='172.20.0.113' --port=8086 --accept-hosts='^*$' 启动代理
- kubectl cluster-info 获取集群服务地址
-
集群配置CA签名双向数字证书认证(可选)
- 所有对apiserver的访问,都是用安全方式https端口443,并且可以对外网提供服务
-
在安全的内网可以使用非安全的访问模式,默认也是非安全模式
openssl genrsa -out rootCA.key 2048 openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$NGROK_DOMAIN" -days 3650 -out rootCA.pem openssl genrsa -out device.key 2048
basic_auth.csv - 基本的用户和密码
ca.crt - 证书颁发机构证书
known_tokens.csv - 令实体(例如,kubelet)可以用来与apiserver通信
kubecfg.crt - 客户端证书,公钥
kubecfg.key - 客户端证书,私钥
server.cert - 服务器证书,公钥
server.key - 服务器证书,私钥
-
集群外部访问集群内Pod或Service
- 设置Pod将容器端口映射到物理机端口上,通过物理机IP加端口号访问
- 设置Service将服务端口号映射到物理机端口上,通过物理机IP加端口号访问
-
直接访问apiserver
需要apiserver 配置--bind-address=0.0.0.0 将证书转换格式 openssl pkcs12 -export -in apiserver.pem -out apiserver.p12 -inkey apiserver-key.pem 在转换过程中可以配置一个密码,tongxingsheng123,再导入的时候需要使用这个密码 就可以使用主机IP地址加6443安全端口号访问 获取访问路径 kubectl cluster-info Kubernetes master is running at https://121.42.248.198:6443 Kibana is running at https://121.42.248.198:6443/api/v1/proxy/namespaces/kube-system/services/kibana-logging KubeDNS is running at https://121.42.248.198:6443/api/v1/proxy/namespaces/kube-system/services/kube-dns kubernetes-dashboard is running at https://121.42.248.198:6443/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard monitoring-grafana is running at https://121.42.248.198:6443/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana
- 二进制安装
cp -r server/bin/{kube-apiserver,kube-controller-manager,kube-scheduler,kubectl,kube-proxy,kubelet} /root/local/bin/
常用操作命令
- kubectl命令格式为 kubectl 子命令 资源类型 资源名 参数 -o=输出日志格式
-
可操作的常用资源类型有:
- deployments 、rc 副本控制
- events 事件
- endpoints
- hpa 横向扩展
- nodes 节点
- namespaces 命名空间
- pods
- pv 数据卷
- services 服务
-
常用子命令:
- apply 从配置文件对资源更新
- cordon 将node隔离出集群调度
- create 从配置文件中创建资源对象
- delete 从配置文件资源名或标签选择器删除资源对象
- describe 描述资源对象的详细信息
- drain 隔离node节点并删除上面的所有pod
- exec pod名 -c 容器名 命令 :在指定容器中执行命令
- get 显示资源对象概要信息
- logs 在屏幕打印一个容器的日志
- rolling-update 对RC进行滚动升级
- scale 扩容缩容pod的数量
- set 修改容器的镜像
- label 设置或更改资源对象的标签
- 输出日志格式(可选参数)json、yaml、wide额外信息
- kubectl create -f 资源定义文件.yaml 创建资源,pod、server、deployment、RC
- kubectl get rc 查看创建的RC文件
- kubectl get pods 查看所有创建的pod
- kubectl describe pod pod的名字 查看具体某一个pod的信息
- kubectl get nodes 查看集群中的node
- kubectl describe noe node的名字 查看具体某一个node的信息,Ready状态表示正常
- kubectl get deployments 查看所有创建的deployments
- kubectl describe deployments 查看具体deployments控制的pod扩展过程
- kubectl scale rc php-slave --replicas=3 手动实现pod扩容缩容
- kubectl get endpoints 查看服务的端点Pod列表
- kubectl exec -ti pod名 /bin/bash 登录指定容器 /bin/ash
- kubectl logs pod名 查看容器日志
- kubectl logs -f pod名 -c 容器名 跟踪查看指定容器日志
- kubectl describe configmap 配置名 查看配置信息
配置
-
Pod资源完整定义,推荐不要直接创建Pod,而是通过RC的模板定义Pod。哪怕只用到一个Pod副本,也强烈建议使用RC来定义
apiVersion: v1 #版本号 kind: Pod # kind定义这个一个pod资源 metadata: name: myweb #定义pod名字 namespace: string #命名空间 labels: #定义标签 name:myweb spec: #定义pod里容器属性 containers: - name: myweb #定义容器名 image: kuberguide/tomcat-app:v1 #定义容器使用镜像 imagePullPolicy:[Always|Never|IfNotPresent]每次都重新下载镜像|仅使用本地镜像|先使用本地镜像,不存在再下载镜像。默认每次重新下载镜像Always command:[string] #容器启动命令列表 args:[string]#容器启动命令参数列表 workingDir:string #容器工作目录 volumeMounts: #挂载到容器的存储卷 - name: string #使用pod定义的共享存储卷名称 mountPath:string 存储卷在容器内挂载的绝对路径,应少于512字符
ports: #定义容器开放暴露的端口号列表
- containerPort: 8080 #定义pod对外开放的服务端口号,容器要监听的端口
env: #定义容器变量列表
- name: MYSQL_SERVICE_HOST
value: 'mysql'
resources: #资源限制设置
limits:
cpu: string #容器启动后最多可用CPU核数。
memory:string #容器启动最多可用内存数 单位MiB、GiB
requests:#最低启动限制设置
cpu: string #最低容器启动可用CPU核数。
memory:string #最低容器启动可用内存数 单位MiB、GiB
restartPolicy:[Always|Never|OnFailure]#pod重启策略,一旦终止立即重启|终止后报告错误后不再重启|只有非0错误码终止才重启其他不重启。默认Always
nodeSelector: #设置调度pod到指定这里配置的labe的Node上
标签key:标签value
imagePullSecrets: #拉取镜像时使用的秘钥信息
- key:string
volumes: #pod的共享存储卷列表
- name: string #存储卷名,唯一
emptyDir:{} #存储卷类型,生命周期和pod相同,临时目录
hostPath: #存储卷类型,表示从宿主机目录上挂载
path: string #使用的宿主机目录
secret: #存储卷类型。
secretName: string
items:
- key: string
path: stirng
configMap: #存储卷类型
name: string
items:
- key: string
path: sting
livenessProbe: #Pod内容器健康检查设置,无响应之后自动重启该容器
exec: #检查类型,仅需使用其中一种。
command:[string] #命令或脚本
httpGet: #检查类型,仅需使用其中一种。
path: string
port: number
host: string
scheme: string
httpHeaders:
- name: string
value: string
tcpSocket: #检查类型,仅需使用其中一种
port: number
initialDelaySeconds:0 #容器重启完成后,首次探测的间隔时间单位秒
timeoutSeconds:0 #容器探测等待响应超时时间,单位秒。默认1秒,超时认为不健康重启
periodSeconds:0 #容器探测间隔时间,单位秒,默认10秒。
successThreshold:0
failureThreshold:0
securityContext:
privileged: false
* Service 服务资源完整定义
apiVersion: v1
kind: Service
metadata: #元数据
name: string #服务名
namespace:string #命名空间
labels:
- name: string #标签列表
spec:
selector: [] #标签选择器
type: string #服务访问方式默认ClusterIP访问、NodePort使用宿主机端口、
clusterIP: string #指定服务IP地址,不指定系统分配
sessionAffinity: ClientIP #是否支持session默认为空轮询负载,ClientIP模式同一个客户端IP请求发到同一pod
ports: #服务开放的端口列表
- name: string #端口名
protocol: string #端口协议 默认TCP 可选UDP
port: int #服务监听端口号
targetPort: int #转发到后端Pod端口号
nodePort: int #映射到宿主机的端口号
status: #外部均衡器设置
loadBalancer:
ingress:
ip: string
hostname: string
* RC 副本控制资源完整定义
* 确保集群中Pod数量就是RC定义中的数量
* 通过RC中的replicas属性来实现系统扩容和缩容
* 通过改变RC中的Pod模板主要是镜像版本,实现系统的滚动升级
apiVersion: v1
kind: ReplicationController
metadata:
name: mysql
spec:
replicas: 1 #副本数量
selector:
name: mysql-pod
template:
metadata:
labels:
name: mysql-pod
spec:
containers:
- name: php-redis
image: redis
env:
- name: HOSTS
value: 1111
ports:
- containerPort: 90
.......
```
-
Secret私密凭据资源完整定义
- 存放私密数据,如密码;OAuth TOken、ssh keys
- 使用:在Docker镜像下载时使用:指定Pod的ImagePullSecrets来引用
- 挂载该secret到Pod来使用,然后访问目录中的文件来获取数据
- 在pod创建时,为pod指定ServiceAccount来自动使用该secret
-
在更新Secret之后,需要删除旧的Pod,再创建一个新的Pod,更新secret的流程和部署一个新的image是一样的
apiVersion: v1 kind: Secret metadata: name: my_secret type: Opaque data: password: 1111 username: 2222 --- kind:pod ..... volumes: - name: foo secret:
......
----
kind:pod
spec:
containers:
- name: foo
image: redis
imagePullSecrets:
- name: my_registrykey #拉取镜像使用
```
-
要求:
- Master:至少1核、2G内存;推荐2核、4G内存,
- 谷歌推荐管理1-5个node节点服务器配置1cpu 4G内存 6-10node 2cpu 8G内存 11-100node 4cpu 15G内存 101-250node 8CPU 30G内存
- Node:至少1核、2G内存;推荐安装需要运行的容器数量进行调整
- 内核系统要求:3.10以上、64位系统、如CentOS7、RedHat7
- Docker要求:至少1.9以上;推荐1.12,目前最新1.13 也就是17.03.1-ce这版
- etcd要求:至少2.0以上;推荐3.0.7版本
功能
kubeconfig 文件
- https://kubernetes.io/docs/co...
- 使用命令修改添加配置集群选项 kubectl config set-cluster 选项
- 使用命令修改用户部分选项 kubectl config set-credentials
- 使用命令修改上下文部分 kubectl config set-context
- 使用命令查看当前加载的配置 kubectl config view
-
分为集群部分、用户部分、上下文部分
current-context: federal-context apiVersion: v1 clusters: - cluster: api-version: v1 server: http://cow.org:8080 name: cow-cluster - cluster: certificate-authority: path/to/my/cafile server: https://horse.org:4443 name: horse-cluster - cluster: insecure-skip-tls-verify: true server: https://pig.org:443
contexts:
-
context:
cluster: horse-cluster namespace: chisel-ns user: green-user
name: federal-context
-
context:
cluster: pig-cluster namespace: saw-ns user: black-user
name: queen-anne-context
kind: Config
users:
- name: blue-user
user:
token: blue-token - name: green-user
user:
client-certificate: path/to/my/client/cert
client-key: path/to/my/client/key
-
默认主机Master的apiserver服务监听8080端口提供REST服务
Node的隔离和恢复
- 在升级Node硬件或维护的情况下,将Node隔离,脱离Kubernetes的调度范围:
脱离之后,系统不会在该nod上创建pod,但已经创建运行的pod不会自动停止,需要手动停止
apiVersion: v1
kind: Node
metadata:
name:k8s-node-1
labels:
hostname: k8s-node-1
spec:
unschedulable: true #表示脱离调度,设置false表示恢复调度
#完成修改命令
kubectl replace -f unschedule node.yaml
#查看node状态,会有所变化
kubectl get nodes
* 通过命令操作:
* kubectl cordon k8s-node-1 隔离
* kubectl uncordon k8s-node-1 恢复
### Node扩容,加入新node节点
* 使用ansible 安装node组件和docker
### 集群环境分组隔离
* 如开发环境、生产环境、测试环境、试错环境、第三方开放服务环境、管理后台环境、内部不同业务组紫色医疗和嘟嘟医生,都可以在一个kubernetes集群中,在不同空间,资源隔离互不影响
* 创建对应命名空间 kubectl create -f namespace-test.yaml
apiVersion: v1
kind: Namespace
metadata:
name: development
---
apiVersion: v1
kind: Namespace
metadata:
name: test
#查看命名空间
kubectl get namespaces
* 命令行创建命名空间 kubectl create namespace test
* 定义运行环境Context,为每个命名空间定义一个运行环境
#定义集群
kubectl config set-cluster kubernetes-cluster --server=https://192.168.1.128.8080
#定义开发环境的运行环境名、使用的命名空间、使用的集群、
kubectl config set-cluster ctx-dev --namespace=development --cluster=kubernetes-cluster --user=dev
#定义测试环境的运行环境名、使用的命名空间、使用的集群、
kubectl config set-cluster ctx-test --namespace=test --cluster=kubernetes-cluster --user=test
#查看定义的运行环境Context
kubectl config view
* 切换当前运行环境,切换之后操作创建的资源都在对应分组环境下,互不干扰
kubectl Config use-context ctx-dev 或切换测试环境
kubectl Config use-context ctx-test
### 全局cpu内存资源管理配置limitRange
* 默认不设置资源限制,pod中的容器会无限制使用内存和cpu。
* 通过Pod中的资源限制可以限制每一个容器使用的内存cpu。但设置每一个pod比较繁琐。可以全局配置统一
* 可以一次限制一个命名空间运行环境下所有容器的最大使用cpu和内存数,给每个不同空间分组不同资源数。
apiVersion: v1
kind: LimitRange
metadata:
name: my_limits
spec:
limits:
- max:#是pod中所有容器的最高上限的总和,一个pod所有容器加起来不能超过
cpu: "4"
memory: 2Gi
min: #是pod中所有容器的最低下限的总和,一个pod所有容器加起来不能少于
cpu: 50m
memory: 100Mi
maxLimitRequestRatio: #限制pod中所有容器的limits值总和和requests值总和的比例上限
cpu: 3
memory: 2
type: pod
- default: #pod中所有未指定限制的容器的上限,值要小于等于max配置的
cpu: 300m
memory: 200Mi
defaultRequest: #Pod中所有未指定限制的容器的下限,只要小于等于default
cpu: 200m
memory:100Mi
max: #pod中所有容器的上限,
cpu: "2"
memory: 1Gi
min: #pod中所有容器的下限,值要小于等于defaultRequest配置的
cpu: 100m
memory: 3Mi
maxLimitRequestRatio: #限制pod中所有容器的limits值和requests值的比例上限
cpu: 5
memory: 4
type: Container
#在使用的命名空间分组创建全局配置
kubectl create -f limits.yaml --namespace=limit-example
#在使用命名空间分组中查看全局限制配置
kubectl describe limits my_limits --namespace=limit-example
### pod服务可靠性
* 一个pod中所有容器都设置了资源限制。并所有容器的Limits值和Requests值全部相等不为0
* 这样的Pod服务在整个集群中是完全可靠的。在资源不够的情况下,最最后才会被杀掉进程释放资源
* 关键服务需要这样的设置,保证服务可靠性
### Etcd服务高可用
* 部署成为集群形式,存储数据使用高可用的存储设备,备份保存,如阿里OSS
* kube-apiserver启动参数配置etcd。使用内网IP
* --etcd-servers=http://10.0.0.1:2379,http://10.0.0.1:2380,http://10.0.0.1:2381,
* 可以部署在同一个服务器上,启动不同端口号;
* 可以部署在docker中,启动多个容器,使用宿主机的端口;方便之后扩展以及升级
* 可以部署在不同服务器上,不同IP,相同端口号;
* 可以只部署一个服务,使用守护进程监控,挂机自动重启。
### Master高可用
* 由于系统不支持多个Master的配置和etcd不同,所以集群部署方式需要使用负载均衡。
* kube-apiserver、kub-controller-manager、kube-scheduler安装在不同服务器中,需要负载均衡haproxy和keepalived健康监控。访问kube-apiserver需要使用负载均衡的地址。另外两个组件需要配置--leader-elect=true配置选举出leader。部署在多台服务器中
* 部署在一台服务器中,使用守护进程监控。
* 部署在一台服务器中,使用容器启动,使用宿主机端口。方便之后扩展以及升级
## 集群监控 cAdvisor + Heapster + Influxdb + Grafana
* http://grafana.org
* http://influxdb.com
* https://github.com/google/cadvisor
* https://github.com/kubernetes/heapster/releases 下载最新版Heapster
* 集群默认集成cAdvisor监控容器的运行状态。采集node性能指标以及node上运行的容器性能指标
* kubelet启动时自动启动cAdvisor服务。在每台Node中运行,单独监控单个Node。对外服务端口号作为web页面查看:4194。访问每个nodeIp地址:4194端口
* cAdvisor + Heapster + Influxdb + Grafana :集群所有容器Node节点监控。
* Heapster:访问每台Node中cAdvisor的api接口获取数据汇总保存到Influxdb。
* Influxdb:分布式时序数据库,每条记录带有时间戳。用于实时的数据采集,事件跟踪,存储时间图表,原始数据。
* Grafana:通过web界面将Influxdb中的时序数据展现成图表
* 安装部署:使用Pod部署,创建3个服务,Influxdb + Grafana创建在同一个Pod中,Heapster在一个Pod中
* Heapster服务 + Influxdb服务都在同一个命名空间中kube-system,不需要区分用户分组
* Influxdb 服务可以通过主机端口号提供访问,通过web界面查看数据
* Grafana 服务可以通过Master的代理模式访问
* Heapster 需要和Master进行安全连接,需要设置CA证书安全模式
* 安装
wget https://github.com/kubernetes...
unzip v1.3.0.zip
mv v1.3.0.zip heapster-1.3.0
cd heapster-1.3.0/deploy/kube-config/influxdb
grafana-deployment.yaml 配置
修改image=dudureg.xip.io:5000/heapster-grafana-amd64:v4.0.2
开启value: /api/v1/proxy/namespaces/kube-system/services/monitoring-grafana/
注释#value:/
为了后续使用 kube-apiserver 或者 kubectl proxy 访问 grafana dashboard
heapster-deployment 配置
修改image=dudureg.xip.io:5000/heapster-amd64:v1.3.0
influxdb-deployment 配置
修改image=dudureg.xip.io:5000/heapster-influxdb-amd64:v1.1.1
修改 数据卷
# emptyDir: {}
hostPath:
path: home/nfs/influxdb_db
时区配置
volumeMounts:
- name: tz-config
mountPath: /etc/localtime
volumes:
- name: tz-config
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
创建所有资源
kubectl create -f .
检查
kubectl get deployments -n kube-system | grep -E 'heapster|monitoring'
检查pods
kubectl get pods -n kube-system | grep -E 'heapster|monitoring'
查看api服务请求地址
kubectl cluster-info
monitoring-grafana is running at https://10.29.167.233:6443/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana
monitoring-influxdb is running at https://10.29.167.233:6443/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb
创建代理访问
kubectl proxy --address='121.42.248.198' --port=8086 --accept-hosts='^*$'
浏览器访问
http://121.42.248.198:8086/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana
### 集群日志 Fluentd + ElasticSearch + Kibana
* 需要配置CA证书安全模式、需要DNS服务
* 服务运行在命名空间kube-system中
* 容器中服务的日志集中输出到Node主机指定目录下
* Fluentd: 在每个Node中运行一个容器,针对Node中的日志目录采集日志,保存到ElasticSearch
* ElasticSearch:保存数据以及索引,需要集群模式分担负载。
* 安装部署:DaemonSet模式在每台Node中启动Fluentd服务Pod容器
* 每个组件都创建自己的rc和服务。使用kubectl cluster-info查看服务地址,使用kubectl proxy命令代理启动访问服务
* 安装
cd /home/kubernetes/cluster/addons/fluentd-elasticsearch
es-controller.yaml 配置
修改
image:dudureg.xip.io:5000/elasticsearch:v2.4.1-2
修改 数据卷
# emptyDir: {}
hostPath:
path: /home/nfs/elasticsearch_db
fluentd-es-ds.yaml 配置
修改
image:dudureg.xip.io:5000/fluentd-elasticsearch:1.22
kibana-controller.yaml 配置
修改
image:dudureg.xip.io:5000/kibana:v4.6.1-1
时区配置
volumeMounts:
- name: tz-config
mountPath: /etc/localtime
volumes:
- name: tz-config
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
查看节点
kubectl get nodes
给节点服务器打标签
kubectl label nodes 10.29.168.24 beta.kubernetes.io/fluentd-ds-ready=true
kubectl label nodes 10.29.167.186 beta.kubernetes.io/fluentd-ds-ready=true
定义 DaemonSet fluentd-es-v1.22 时设置了 nodeSelector beta.kubernetes.io/fluentd-ds-ready=true ,所以需要在期望运行 fluentd 的 Node 上设置该标签
创建资源
kubectl create -f .
查看
kubectl get deployment -n kube-system|grep kibana
kubectl get pods -n kube-system|grep -E 'elasticsearch|fluentd|kibana'
kubectl get service -n kube-system|grep -E 'elasticsearch|kibana'
kibana Pod 第一次启动时会用较长时间(10-20分钟)来优化和 Cache 状态页面,可以 tailf 该 Pod 的日志观察进度:
kubectl logs kibana-logging-3358050253-xpwpz -n kube-system -f
api服务访问
kubectl cluster-info
代理访问
kubectl proxy --address='121.42.248.198' --port=8087 --accept-hosts='^*$'
http://121.42.248.198:8087/api/v1/proxy/namespaces/kube-system/services/kibana-logging
在 Settings -> Indices 页面创建一个 index(相当于 mysql 中的一个 database),选中 Index contains time-based events,使用默认的 logstash-* pattern,点击 Create ;
如果你在这里发现Create按钮是灰色的无法点击,且Time-filed name中没有选项,fluentd要读取/var/log/containers/目录下的log日志,这些日志是从/var/lib/docker/containers/${CONTAINER_ID}/${CONTAINER_ID}-json.log链接过来的,查看你的docker配置,—log-driver需要设置为json-file格式,默认的可能是journald,参考docker logging。
### 报警提醒 AlertManager、ElastAlert、Stackdriver
### API网关服务 Kong + Cassandra
* Cassandra:分布式NoSql数据库
* Kong:需要在每台Node节点中运行服务。使用DaemonSet模式
### 事务追踪系统 Appdash、淘宝鹰眼、Zipkin
### 后台任务处理系统 Resque、Sidekiq、Delayed_job
### 事件驱动消息队列 Redis、Mq、Gearman
### CI/CD持续集成 Jenkins
### 负载均衡 Traefik、Nginx、LVS、HAProxy
### PHP7环境 部署
* 1. php服务包括nginx、php-fpm、memcache、scribe等几大组件。
* 2. 将PHP服务相关的组件制作成一个镜像。服务通过容器命令来启动。nginx+php+memecache
* 3. 代码、配置、日志等经常变更部分通过挂载的方式和docker容器互动。代码镜像使用busybox为基础,大小仅1M
* 镜像制作
1. 从镜像仓库里拉去CentOS作为基础镜像。
2. 运行镜像
3. 在运行容器中安装PHP环境相关软件包。
4. 提交修改并推送至仓库。
5. PHP服务镜像制作完毕
* 代码镜像制作
- Dockerfile
FROM registry.x.weibo.com/qinglong/busybox
RUN mkdir -p /code/x.weibo.com
ADD x.weibo.com /code/x.weibo.com
- Build
registry.x.weibo.com/codeimg_x_weibo_com_git:324234
- 下载代码镜像、启动容器、拷贝代码
docker pull registry.x.weibo.com/codeimg_x_weibo_com_git:324234
docker run -name=code_container -t -i -d /phpcode codeimg_x_weibo_com_git:
324234
docker exec code_container cp -R /phpcode /code/x.weibo.com
* 配置文件镜像制作
* 配置文件制作成docker镜像
* 每台机器拉取镜像,替换配置文件
* 自定义脚本执行reload 重启加载新配置文件生效
* 容器的优雅重启采用docker exec xx reload 命令
### 复用包管理 Helm Chart
* 是一个用于Kubernetes的包管理工具,自动安装流行软件包,可重复构建,可配合持续化集成
* https://github.com/kubernetes/helm
* 分为客户端和服务端,客户端安装在笔记本上,服务端在集群中运行。
* 客户端安装:brew install kubernetes-helm
* 服务端安装:
#Kubernetes 必须 1.4.1以上,本地必须有kubectl命令工具
#通过读取$HOME/.kube/config 路径下的Kubernetes配置文件来决定安装服务端的环境,和kubectl命令工具使用的是同一个配置文件
#查看安装到哪个集群,查看当前运行环境
kubectl config current-context
#本地初始化:helm init --kube-context=安装到指定集群,默认为当前环境
#升级服务端:helm init --upgrade
#helm同样需要从谷歌拉取镜像,需要在本地仓库保存一份
#镜像使用问题,如果包配置中使用镜像拉取策略是使用远程的镜像,可以去kubernetes的UI界面中修改调度配置文件改成imagePullPolicy:IfNotPresent 即可或者使用命令行修改更新,或直接修改使用的镜像文件为本地的
* 安装流程软件包:同一个包可以多次在同一集群环境中安装,并都能单独管理升级
* helm search 查看可安装的包列表
* helm repo update 更新资源列表;
* helm install stable/mysql --name 新名字 安装稳定版 kubectl describe services 查看服务
* helm inspect stable/mysql 了解查看包功能
* helm ls 查看已经发布的包
* helm list 查看已经部署的包
* helm delete 发布包名 删除发布的包
* helm status 发布包名 查看发布的包状态,配置信息,ip等信息
* helm rollback happy-panda 1 回滚包
* helm upgrade 升级包
* helm get -h 帮助命令
* helm --debug 调试模式,输出命令的具体执行信息
* https://github.com/kubernetes/charts/tree/master/stable/ 常见包github地址
* 常见包stable/datadog、stable/grafana、stable/influxdb、stable/jenkins、stable/memcached、stable/mongodb、stable/mysql、stable/redis、stable/postgresql、stable/openvpn、stable/rabbitmq、stable/cockroachdb数据库、stable/traefik负载均衡、stable/testlink测试软件、stable/owncloud私有云、stable/minio分布式存储、stable/redmine项目管理、stable/prometheus服务监控系统、stable/gitlab-ce版本管理、
* stable/wordpress博客、stable/phpbb论坛、stable/prestashop电商、stable/opencart电商、stable/joomla框架、stable/drupal框架、stable/osclass分类信息系统、stable/orangehrm人力资源、stable/odoo企业ERP、stable/mediawiki百科、stable/dokuwiki微型百科、
### 垃圾回收机制
* 集群中创建的不再使用的容器和镜像会定期被清理,每分钟清理一次容器,每5分钟清理一次镜像
* 只能清理被kubelet管理的容器。
* 镜像清理,只会根据磁盘的使用率来触发
## 调试
* kubectl describe 命令很有用
* 查询系统事件: kubectl describe pod 查看一个Pod的详细信息,其中Event事件信息对排错有用
* 查看容器日志: kubectl logs PodName -c 容器名
* 注意将集群的日志在启动参数中集中配置在指定目录中。
* 主要从Kubelet中查看Pod的完整日志、kube-controller-manager日志、kube-scheduler日志、kube-proxy日志、防火墙
## 优化
## 常见问题
* 经常遇见谷歌域名在Mac环境下DNS解析IP地址出错,结果超时无法访问谷歌服务器下载镜像等文件
* 可以查看域名对应解析的IP如:host kubernetes-charts.storage.googleapis.com
* 使用ping命令ping域名出来的IP地址不一致的话可以清理DNS缓存:
* Mac下:sudo killall -HUP mDNSResponder
* Liunx下:systemctrl restart nscd或/etc/init.d/nscd restart
* 时区配置
ls -l /etc/localtime
spec:
containers:
- name: my-testpod
image: 1604podimage:latest
volumeMounts:
- name: tz-config
mountPath: /etc/localtime
volumes:
- name: tz-config
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
## 实际应用
* https://kubernetes.io/docs/samples/ 官方范例
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。