1. skywalking—docker镜像构建k8s部署
前言
skywalking是个非常不错的apm产帆闭品,但是在使用过程中有个非常蛋疼的问题,在基于es的存储情况下,es的数据一有问题,就会导致整个skywalking web ui服务不可用,然后需要agent端一个服务一个服亏汪务的停用,然后服务重新部署后好,全部走一遍。这种问题同样也会存在skywalking的版本升级迭代中。而且apm 这种过程数据是允许丢弃的,默认skywalking中关于trace的数据记录只保存了90分钟。故博主准备将skywalking的部署容器化,一键部署升级。下文是整个skywalking 容器化部署的过程。
目标:将skywalking的docker镜像运行在k8s的集群环境中提供服务
docker镜像构建
FROMregistry.cn-xx.xx.com/keking/jdk:1.8ADDapache-skywalking-apm-incubating/ /opt/apache-skywalking-apm-incubating/RUNln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo 'Asia/Shanghai' >/etc/timezone \
&& chmod +x /opt/apache-skywalking-apm-incubating/config/setApplicationEnv.sh \
&& chmod +x /opt/apache-skywalking-apm-incubating/webapp/setWebAppEnv.sh \
&& chmod +x /opt/apache-skywalking-apm-incubating/bin/startup.sh \
&& echo "tail -fn 100 /opt/apache-skywalking-apm-incubating/logs/webapp.log" >> /opt/apache-skywalking-apm-incubating/bin/startup.shEXPOSE8080 10800 11800 12800CMD/opt/apache-skywalking-apm-incubating/态空裂config/setApplicationEnv.sh \
&& sh /opt/apache-skywalking-apm-incubating/webapp/setWebAppEnv.sh \
&& /opt/apache-skywalking-apm-incubating/bin/startup.sh
在编写Dockerfile时需要考虑几个问题:skywalking中哪些配置需要动态配置(运行时设置)?怎么保证进程一直运行(skywalking 的startup.sh和tomcat中 的startup.sh类似)?
application.yml
#cluster:# zookeeper:# hostPort: localhost:2181# sessionTimeout: 100000naming:jetty:#OS real network IP(binding required), for agent to find collector clusterhost:0.0.0.0port:10800contextPath:/cache:# guava:caffeine:remote:gRPC:# OS real network IP(binding required), for collector nodes communicate with each other in cluster. collectorN --(gRPC) --> collectorMhost:#real_hostport:11800agent_gRPC:gRPC:#os real network ip(binding required), for agent to uplink data(trace/metrics) to collector. agent--(grpc)--> collectorhost:#real_hostport:11800# Set these two setting to open ssl#sslCertChainFile: $path#sslPrivateKeyFile: $path# Set your own token to active auth#authentication: xxxxxxagent_jetty:jetty:# OS real network IP(binding required), for agent to uplink data(trace/metrics) to collector through HTTP. agent--(HTTP)--> collector# SkyWalking native Java/.Net/node.js agents don't use this.# Open this for other implementor.host:0.0.0.0port:12800contextPath:/analysis_register:default:analysis_jvm:default:analysis_segment_parser:default:bufferFilePath:../buffer/bufferOffsetMaxFileSize:10MbufferSegmentMaxFileSize::trueui:jetty:# Stay in `localhost` if UI starts up in default mode.# Change it to OS real network IP(binding required), if deploy collector in different machine.host:0.0.0.0port:12800contextPath:/storage:elasticsearch:clusterName:#elasticsearch_:trueclusterNodes:#elasticsearch_clusterNodesindexShardsNumber:2indexReplicasNumber:0highPerformanceMode:true# Batch process setting, refer to https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.5/java-docs-bulk-processor.htmlbulkActions:2000# Execute the bulk every 2000 requestsbulkSize:20# flush the bulk every 20mbflushInterval:10# flush the bulk every 10 seconds whatever the number of requestsconcurrentRequests:2# the number of concurrent requests# Set a timeout on metric data. After the timeout has expired, the metric data will automatically be deleted.traceDataTTL:2880# Unit is minuteminuteMetricDataTTL:90# Unit is minutehourMetricDataTTL:36# Unit is hourdayMetricDataTTL:45# Unit is daymonthMetricDataTTL:18# Unit is month#storage:# h2:# url: jdbc:h2:~/memorydb# userName: saconfiguration:default:#namespace: xxxxx# alarm :2000serviceErrorRateThreshold:10.::10.::10.:2000# ::40# max collection's size of worker cache collection, setting it smaller when collector OutOfMemory crashed.workerCacheMaxSize:10000#receiver_zipkin:# default:# host: localhost# port: 9411# contextPath: /
webapp.yml
动态配置:密码,grpc等需要绑定主机的ip都需要运行时设置,这里我们在启动skywalking的startup.sh只之前,先执行了两个设置配置的脚本,通过k8s在运行时设置的环境变量来替换需要动态配置的参数
setApplicationEnv.sh
#!/usr/bin/env shsed -i"s/#elasticsearch_clusterNodes/${elasticsearch_clusterNodes}/g"/opt/apache-skywalking-apm-incubating/config/application.ymlsed -i"s/#elasticsearch_clusterName/${elasticsearch_clusterName}/g"/opt/apache-skywalking-apm-incubating/config/application.ymlsed -i"s/#real_host/${real_host}/g"/opt/apache-skywalking-apm-incubating/config/application.yml
setWebAppEnv.sh
#!/usr/bin/env shsed -i"s/#skywalking_password/${skywalking_password}/g"/opt/apache-skywalking-apm-incubating/webapp/webapp.ymlsed -i"s/#real_host/${real_host}/g"/opt/apache-skywalking-apm-incubating/webapp/webapp.yml
保持进程存在:通过在skywalking 启动脚本startup.sh末尾追加"tail -fn 100
/opt/apache-skywalking-apm-incubating/logs/webapp.log",来让进程保持运行,并不断输出webapp.log的日志
Kubernetes中部署
apiVersion:extensions/v1beta1kind:Deploymentmetadata:name:skywalkingnamespace:uatspec:replicas:1selector:matchLabels:app:skywalkingtemplate:metadata:labels:app:skywalkingspec:imagePullSecrets:-name:registry-pull-secretnodeSelector:apm:skywalkingcontainers:-name:skywalkingimage:registry.cn-xx.xx.com/keking/kk-skywalking:5.2imagePullPolicy:Alwaysenv:-name:elasticsearch_clusterNamevalue:elasticsearch-name:elasticsearch_clusterNodesvalue:172.16.16.129:31300-name:skywalking_passwordvalue:xxx-name:real_hostvalueFrom:fieldRef:fieldPath:status.podIPresources:limits:cpu:1000mmemory:4Girequests:cpu:700mmemory:2Gi---apiVersion:v1kind:Servicemetadata:name:skywalkingnamespace:uatlabels:app:skywalkingspec:selector:app:skywalkingports:-name:web-aport:8080targetPort:8080nodePort:31180-name:web-bport:10800targetPort:10800nodePort:31181-name:web-cport:11800targetPort:11800nodePort:31182-name:web-dport:12800targetPort:12800nodePort:31183type:NodePort
Kubernetes部署脚本中唯一需要注意的就是env中关于pod ip的获取,skywalking中有几个ip必须绑定容器的真实ip,这个地方可以通过环境变量设置到容器里面去
结语
整个skywalking容器化部署从测试到可用大概耗时1天,其中花了个多小时整了下谭兄的skywalking-docker镜像(
https://hub.docker.com/r/wutang/skywalking-docker/),发现有个脚本有权限问题(谭兄反馈已解决,还没来的及测试),以及有几个地方自己不是很好控制,便build了自己的docker镜像,其中最大的问题还是解决集群中网络通讯的问题,一开始我把skywalking中的服务ip都设置为0.0.0.0,然后通过集群的nodePort映射出来,这个时候的agent通过集群ip+31181是可以访问到naming服务的,然后通过naming服务获取到的collector gRPC服务缺变成了0.0.0.0:11800, 这个地址agent肯定访问不到collector的,后面通过绑定pod ip的方式解决了这个问题。
2. Jenkins+Rancher自动化部署
本文主要记录Jenkins+Rancher+k8s自动化部署相关配置说明,不涉及rancher和jenkins安装部署,包含java server项目、WAR项目、前端VUE项目部署配置介绍。
服务器环境信息:
需要在安装jenkins服务上部署下面相应的软件,请注意软件版本,如已经安装相关软件,可跳过此章节。
需要安装rancher-cli,并且使用jenkins用户预先登录rancher平台:命令参考:
--token:这个用户的token建议设置为永不过期,在rancher管理端 -> api&key > 添加。
建议安装阿里镜像,提高编译速度:
jenkins启动用户需要添加到docker组中:
项目主要是java和vue开发的,所以需要安装Maven Integration plugin插件。
spring boot或者spring cloud自带容器,以及其它服务类型的java后端应用部署。
1、填写项目名称,选择"构建一个maven项目"
点击下面"OK"按钮
2、填写项目描述信息
3、输入项目地址,并选择用户凭证
本文通过conding.net作为代码管理平台,点击"Add"添加自己账号凭证(输入coding.net平台登陆账号密码即可)。
4、配置maven编译脚本
5、编写rancher部署脚本
Dockerfile参数说明:FROM:选择基础镜像包,该项目是用java语言开发需要jdk1.8所以选择openjdk:8ADD:将bRule-deploy-1.0.0.tar.gz文件解压并上传到镜像的brule目录EXPOSE:容器内部启动2002端口,根据自身项目填写指定端口,多个端口填写多行EXPOSE标签ENTRYPOINT:容器启动时执行的命令,执行多条命令使用&&拼接,命令行中带&需要加上转移符\&,使用tail -fn监听应用日志,以便容器日志查看。
用于创建docker镜像,就好比创建一个已经安装并且配置好了应用程序的操作系统镜像。
参数说明:192.168.100.21:5000:为本地docker镜像服务器地址brule:latest:应用名称,根据自身项目名称修改
利用上面创建好的操作系统镜像启动一个vmware虚拟机,创建k8s容器。
参数说明:brule:应用名称,根据自身项目名称修改,应用名称规范?(.?)*image:刚才创建的docker镜像containerPort:容器启动端口,多个端口使用多行containerPort标签声明,端口限制在【30000-32000】
前面vmware虚拟机创建好后,怎么能让别人访问?这个时候就需要创建一个网络服务,用于打通路由器与vmware本地虚拟机的网络。
参数说明:brule:应用名称,根据自身项目名称修改port:容器启动端口nodePort:对外提供服务端口,外部机器访问
将上面配置好的shell脚本复制到Post Steps -> 执行shell文本域中,并点击"保缓缓缓存" -> "立即构建"即可部署。
1、进入刚才创建好的jenkins任务,点击立即构建
2、点击左下角构建任务,选择"Console Output"哪唯,查看构建日志
3、登录rancher管理平台,查看构建好的应用
基于J2EE项目的war包部署,前面操作都一致,只是shell部署脚本稍有不同,这里主要详细说明rancher部署脚本。
Dockerfile参数说明:FROM:选择基础镜像包,war统一使用tomcat容器部署,tomcat:8.5-jre8-slimADD:将operation.war文件解压并上传到镜像的/usr/local/tomcat/webapps/目录EXPOSE:容器内部启动8080端口,根据自身项目填写指定端口,多个端扰模口填写多行EXPOSE标签
这里不需要配置ENTRYPOINT标签,因为tomcat镜像包中已经有了。
用于创建docker镜像,就好比创建一个已经安装并且配置好了应用程序的操作系统镜像。
参数说明:192.168.100.21:5000:为本地docker镜像服务器地址operation:latest:应用名称,根据自身项目名称修改
利用上面创建好的操作系统镜像启动一个vmware虚拟机,创建k8s容器。
参数说明:operation:应用名称,根据自身项目名称修改image:刚才创建的docker镜像containerPort:容器启动端口,多个端口使用多行containerPort标签声明,端口限制在【30000-32000】
前面vmware虚拟机创建好后,怎么能让别人访问?这个时候就需要创建一个网络服务,用于打通路由器与vmware本地虚拟机的网络。
参数说明:operation:应用名称,根据自身项目名称修改port:容器启动端口nodePort:对外提供服务端口,外部机器访问
将上面配置好的shell脚本复制到Post Steps -> 执行shell文本域中,并点击"保存" -> "立即构建"即可部署。
基于webpack构建的VUE项目部署,前面操作都一致,只是shell部署脚本稍有不同,这里主要详细说明rancher部署脚本。
Dockerfile参数说明:FROM:选择基础镜像包,前端统一使用tomcat容器部署,tomcat:8.5-jre8-slimCOPY:将/dist目录上传到镜像的/usr/local/tomcat/webapps/fastquery/目录EXPOSE:容器内部启动8080端口,根据自身项目填写指定端口,多个端口填写多行EXPOSE标签
这里不需要配置ENTRYPOINT标签,因为tomcat镜像包中已经有了。
用于创建docker镜像,就好比创建一个已经安装并且配置好了应用程序的操作系统镜像。
参数说明:192.168.100.21:5000:为本地docker镜像服务器地址operation:latest:应用名称,根据自身项目名称修改
利用上面创建好的操作系统镜像启动一个vmware虚拟机,创建k8s容器。
前面vmware虚拟机创建好后,怎么能让别人访问?这个时候就需要创建一个网络服务,用于打通路由器与vmware本地虚拟机的网络。
参数说明:shutcm-fastquery-web:应用名称,根据自身项目名称修改port:容器启动端口nodePort:对外提供服务端口,外部机器访问
将上面配置好的shell脚本复制到Post Steps -> 执行shell文本域中,并点击"保存" -> "立即构建"即可部署。
3. k8s部署springboot项目
环境和前面中 kubeadm 搭建 k8s 的一致
省略创建项目步骤
提供一个 /k8s/hello 接口 接收一个 name 参数,打印并且返回
可以看到 2个 副本pod 已经Running
访问前 需肆闷要先把 springboot.demo.com 域名添加到 宿主机的 /etc/hosts中 保证可以正常解析到并坦 ingress-nginx那台机器上的nginx 即可 (不详 可以看上一篇)
请求接口: http://springboot.demo.com/k8s/hello?name=johnny
查看 两个副本的 日裂蔽弯志,可以看到 Ingress 的默认轮训负载均衡策略也生效了 ,至此 k8s部署springboot项目已经结束
本篇主要 讲解了 k8s 如何部署springboot项目,过程很简单 ,目前只是半手动部署,后面引入 CICD 实现真正的 自动化部署。
欢迎大家访问个人博客 : https://www.askajohnny.com
4. Mac部署k8s
官网地址: https://www.docker.com/procts/docker-desktop
1:翻墙问题,Docker Desktop默认去国外拉取镜像,不能翻墙或者翻墙网速慢的小伙伴只能干着急。推荐一个开源项目: https://github.com/AliyunContainerService/k8s-for-docker-desktop ,作者提供了一个脚本核帆,将从阿里源拉取镜像到本地,
2:检查hosts文件,确定大者是否有硬解析:127.0.0.1 kubernetes.docker.internal
默认会自动加,对于用hosts切换工具的小伙伴来说,需要注意一下,否则就会有滚氏薯一下问题:
dial tcp: lookup kubernetes.docker.internal: no such host
部署 Kubernetes dashboard:
检查 kubernetes-dashboard 应用状态:
开启 API Server 访问代理:
通过如下 URL 访问 Kubernetes dashboard:
http://127.0.0.1:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
配置控制台访问令牌:
5. K8s系统部署kubelet服务
kubelet 是在每个 Node 节点上运行的主要 “节点代理”。它可以使用以下之一向 apiserver 注册: 主机名(hostname);覆盖主机名的参数;某云驱动哗仿唤的特定逻辑。
kubelet 是基于 PodSpec 来工作的。每个 PodSpec 是一个描述 Pod 的 YAML 或 JSON 对象。 kubelet 接受通过各种机制(主要是通过 apiserver)提供的一组 PodSpec,并确保这些 PodSpec 中描述的容器处于运行状态且运行状况良好。 kubelet 不管理不乱凯是由 Kubernetes 创建的容器。
在hdss01-221.host.com和hdss01-222.host.com:主机上操作:
签发kubelet证书:
在运维主机hdss01-200.host.com上:
创建生成证书签名请求(csr)的json配置文件:
hosts:要把使用和可能使用的ip地址都写上。( 一定要先规划好 )
~]# cd /opt/certs/
certs]# vi kubelet-csr.json
{
"CN": "k8s-kubelet",
"hosts": [
"127.0.0.1",
"10.41.1.210",
"10.41.1.221",
"10.41.1.222",
"10.41.1.223",
"10.41.1.224",
"10.41.1.225",
"10.41.1.226",
"10.41.1.227",
"10.41.1.228"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "henan",
"L": "zhengzhou",
"O": "jx",
"OU": "xxzx"
}
]
}
certs]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server kubelet-csr.json |cfssl-json -bare kubelet
把证书复制到运算节点hdss01-221.host.com和大御hdss01-222.host.com上:
cd /opt/kubernetes/server/bin/cert
scp hdss01-200:/opt/certs/kubelet.pem .
scp hdss01-200:/opt/certs/kubelet-key.pem
创建配置kubelet.kubeconfig:
只做一次,最后生成的 kubelet.kubeconfig 拷贝至其他节点
conf]# cd /opt/kubernetes/server/bin/conf
set-cluster:
kubectl config set-cluster myk8s
--certificate-authority=/opt/kubernetes/server/bin/cert/ca.pem
--embed-certs=true
--server=https://10.41.1.210:7443
--kubeconfig=kubelet.kubeconfig
set-credentials:
kubectl config set-credentials k8s-node
--client-certificate=/opt/kubernetes/server/bin/cert/client.pem
--client-key=/opt/kubernetes/server/bin/cert/client-key.pem
--embed-certs=true
--kubeconfig=kubelet.kubeconfig
set-context:
kubectl config set-context myk8s-context
--cluster=myk8s
--user=k8s-node
--kubeconfig=kubelet.kubeconfig
use-context:
kubectl config use-context myk8s-context --kubeconfig=kubelet.kubeconfig
创建资源配置文件(给用户k8s-node授予权限):
conf]# cat /opt/kubernetes/server/bin/conf/k8s-node.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: k8s-node
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:node
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: k8s-node
conf]# kubectl create -f k8s-node.yaml
conf]# kubectl get clusterrolebinding k8s-node -o yaml
在hdss01-222.host.com上:
cert]# cd /opt/kubernetes/server/bin/conf
conf]# scp hdss01-221:/opt/kubernetes/server/bin/conf/kubelet.kubeconfig .
准备pause基础镜像:
在运维主机hdss01-200.host.com上操作:
下载镜像:
certs]# docker pull kubernetes/pause
给镜像打tag
certs]# docker tag f9d5de079539 harbor.od.com/public/pause:latest
上传到私有库:
certs]# docker push harbor.od.com/public/pause:latest
创建kubelet启动脚本:
hdss01-221.host.com上:
cat /opt/kubernetes/server/bin/kubelet.sh
#!/bin/sh
./kubelet
--anonymous-auth=false
--cgroup-driver systemd
--cluster-dns 192.168.0.2
--cluster-domain cluster.local
--runtime-cgroups=/systemd/system.slice
--kubelet-cgroups=/systemd/system.slice
--fail-swap-on="false"
--client-ca-file ./cert/ca.pem
--tls-cert-file ./cert/kubelet.pem
--tls-private-key-file ./cert/kubelet-key.pem
--hostname-override hdss01-221.host.com #hdss01-222做相应的更改 hdss01-222.host.com
--image-gc-high-threshold 20
--image-gc-low-threshold 10
--kubeconfig ./conf/kubelet.kubeconfig
--log-dir /data/logs/kubernetes/kube-kubelet
--pod-infra-container-image harbor.od.com/public/pause:latest
--root-dir /data/kubelet
bin]# chmod +x kubelet.sh
bin]# mkdir -p /data/logs/kubernetes/kube-kubelet /data/kubelet
创建supervisor配置:
hdss01-221.host.com上:
bin]# cat /etc/supervisord.d/kube-kubelet.ini
[program:kube-kubelet-01-221] #hdss01-222.host.com上修改改为22
command=/opt/kubernetes/server/bin/kubelet.sh ; the program (relative uses PATH, can take args)
numprocs=1 ; number of processes copies to start (def 1)
directory=/opt/kubernetes/server/bin ; directory to cwd to before exec (def no cwd)
autostart=true ; start at supervisord start (default: true)
autorestart=true ; retstart at unexpected quit (default: true)
startsecs=30 ; number of secs prog must stay running (def. 1)
startretries=3 ; max # of serial start failures (default 3)
exitcodes=0,2 ; 'expected' exit codes for process (default 0,2)
stopsignal=QUIT ; signal used to kill process (default TERM)
stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10)
user=root ; setuid to this UNIX account to run the program
redirect_stderr=true ; redirect proc stderr to stdout (default false)
stdout_logfile=/data/logs/kubernetes/kube-kubelet/kubelet.stdout.log ; stderr log path, NONE for none; default AUTO
stdout_logfile_maxbytes=64MB ; max # logfile bytes b4 rotation (default 50MB)
stdout_logfile_backups=4 ; # of stdout logfile backups (default 10)
stdout_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0)
stdout_events_enabled=false ; emit events on stdout writes (default false)
bin]# supervisorctl update
bin]# supervisorctl status
bin]# kubectl get nodes
ROlES添加标签,设定节点角色,可同时加两个标签
bin]#kubectl label node hdss01-221.host.com node-role.kubernetes.io/master=
bin]# kubectl label node hdss01-221.host.com node-role.kubernetes.io/node=
bin]#kubectl label node hdss01-222.host.com node-role.kubernetes.io/node=
bin]# kubectl label node hdss01-222.host.com node-role.kubernetes.io/master=
6. K8S 应用启停通用脚本
Kubernetes 集群中缺顷运行的应用中的每一个服务组件通常是以 Deployment 的形式存在的,本文中提供的管理脚本假设读者部署在 Kubernetes 中的应用服务的 Deployment 对象均已特定的前缀命名,比如 demo,那么集群中可能存在一下的 Deployment 对象:
在这个前提下,我这里提供了者模一个脚本可以对这些 deployment 对象进行一键启停操作。举例说明,加绒我的脚本名称为 k8s-apps.sh 那么可以执行如下命令:
启停脚本的内容如下:伏嫌陆
7. k8s的咖啡伴侣 -- 自动化部署工具Drone
刚开始打算用Jenkins+shell 部署镜像到K8S,无意间看到网上推荐的drone,用了之后觉得drone和docker、K8S非常般配,Jenkins更像上一并庆陆代产品。在这里分享和总结一下drone的使用过程。
目录结构
通过以上脚本,就实现了自动化部署,drone的功能很简洁,没有绝顷一丝多余,最后放一张部署成功的截图差信
8. 8. K8s 资源部署
很少在 Kubernetes 中直接创建一个Pod,甚至是单实例(Singleton)的 Pod。 这是因为 Pod 被设计成了相对临时性的、用后即抛的一次性实体, 不支持高可用 。一般使用工作负载资源来创建和管理多个 Pod。 资源的控制器能够处理副本的管理、上线,并在 Pod 失效时提供自愈能力。
能够管理一个或者多个 Pod 的工作负载资源有:
Pod 类似于共享namesapce、cgroup、文件系统卷的一组 Docker 容器。创建Pod时,除了会创建1个或多个工作容器外, 还会额外在Pod中创建Pod容器,Pod容器用于实现k8s的各种功能 。
查询基础信息
查询详细信息
查询Pod的标签
ReplicationController 确保在任何时候都有特定数量的 Pod 副本处于运行状态。 换句话说,ReplicationController 确保一个 Pod 或一组同类的 Pod 总是可用的。
RC会根据 spec.selector 将当前已经运行的Pod加入RC,当 Pod 数量过多时,ReplicationController 会终止多余的 Pod。当 Pod 数量世腊太少时,ReplicationController 将会启动新的 Pod。
查询基础信息
查询详细信息
问题:
Pod创建完成后,如何访问Pod呢?直接访问Pod会有如下几个问题:
解决方法:
Kubernetes中的Service对象就是用来解决上述Pod访问问题的。Service有一个固定IP地址 Cluster IP ,Service将访问它的流量转发给Pod,具体转发给哪些Pod通过Label来选择,而且Service可以给这些Pod做负载均衡。
Node物理节点的IP地址
Service的IP地址,此为虚拟IP地址。外部网络无法ping通,只有kubernetes集群内部访问使用。
每个Pod的IP地址
Cluster地址和pod地址在不同网段,Cluster地址为虚拟地址,不配在pod上或主机上,外部访问时,先到Node节点网络(所有Node开放同一个端口号),再转到service网络,最后代理册返兄给pod网络。
Service的类型决定了如何向外暴露Service
通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是默认的 ServiceType。
通过每个节点上的 IP 和静态端口(NodePort)暴露服务。 NodePort 服务会路由到自动创建的 ClusterIP 服务。 通过请求 <Node节点 IP>:<节点端口>,你可以从集群的外部访问一个 NodePort 服务。
NodePort类型的Service例子:
Service默认的负载均衡模式是RR轮询模式,可以通过修改 spec.sessionAffinity 为 ClientIP 来实现源地址会话保持。可以设置会话保持的超时时间(默认时间是10800s),设置 spec.sessionAffinityConfig.clientIP.timeoutSeconds 的值。
Deployment 管州袭理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能,
首先根据文件创建deployment,加入 --record 参数来记录历史,方便在回滚时查看针对每个 Deployment 修订版本所执行过的命令。
Deployment会创建ReplicaSet,ReplicaSet负责启动Pods。ReplicaSet 的名称始终被格式化为 [Deployment名称]-[随机字符串] 。 其中的随机字符串是使用 pod-template-hash 作为种子随机生成的。
Deployment 控制器每次注意到新的 Deployment 时,都会创建一个 ReplicaSet 以启动所需的 Pods。 如果更新了 Deployment,则控制标签匹配 .spec.selector 但模板不匹配 .spec.template 的 Pods 的现有 ReplicaSet 被缩容。最终,新的 ReplicaSet 缩放为 .spec.replicas 个副本, 所有旧 ReplicaSets 缩放为 0 个副本。
当 Deployment 正在上线时被更新,Deployment 会针对更新创建一个新的 ReplicaSet 并开始对其扩容,之前正在被扩容的 ReplicaSet 会被翻转,添加到旧 ReplicaSets 列表 并开始缩容。
例如,假定你在创建一个 Deployment 以生成 nginx:1.14.2 的 5 个副本,但接下来 更新 Deployment 以创建 5 个 nginx:1.16.1 的副本,而此时只有 3 个nginx:1.14.2 副本已创建。在这种情况下,Deployment 会立即开始杀死 3 个 nginx:1.14.2 Pods, 并开始创建 nginx:1.16.1 Pods。它不会等待 nginx:1.14.2 的 5 个副本都创建完成 后才开始执行变更动作。
升级操作,两种方式:
Deployment之所以能如此容易的做到回滚,是因为Deployment是通过ReplicaSet控制Pod的,升级后之前ReplicaSet都一直存在,Deployment回滚做的就是使用之前的ReplicaSet再次把Pod创建出来。Deployment中保存ReplicaSet的数量可以使用 revisionHistoryLimit 参数限制,默认值为10。
查看Deployment 修订历史
输出
查看第n次的修订历史
输出
回滚到之前的修订版本
回滚后,Deployment 修订历史发生变化,revision 1变为revision 3
可以在触发一个或多个更新之前暂停 Deployment,然后再恢复其执行。 这样做使得你能够在暂停和恢复执行之间应用多个修补程序,而不会触发不必要的上线操作。
暂停
恢复
通过检测容器响应是否正常来决定是否重启Pod,Kubernetes支持如下三种探测机制:
Liveness Probe在 containers 字段中定义
为Deployment中的Pod配置Liveness Probe,Probe往容器的80端口发送HTTP GET请求,如果请求不成功,Kubernetes会重启容器。
在容器中执行 cat /tmp/healthy 命令,如果成功执行并返回 0 ,则说明容器是健康的。