k8s

安装配置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-keysecret: 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-useruser: token: blue-token
name: green-useruser: 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/ 官方范例

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理