导读
kubernetes(简称k8s)使开发者可以自主部署应用,并且控制部署的频率,完全脱离运维团队的帮助。更多的概念请参考相关书籍,本文通过一个简单的demo让http服务在k8s环境下跑起来,面向入门用户。
写一个最简单的http demo
鉴于golang在部署方面的简单和无依赖性,本文的demo通过golang来实现,功能很简单,代码如下:
// main.gopackage mainimport ("fmt""net/http")func IndexHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "hello k8s")}func main() {http.HandleFunc("/", IndexHandler)http.ListenAndServe(":8888", nil)}
编译
编译注意事项:(1)由于最终打包的docker镜像是linux系统,本地编译go应用的时候需要指定GOOS参数。(2)如果本地没有golang环境,可以通过golang docker对源码进行编译。(3)可以将编译和构建镜像一起实现,参考后面构建镜像的说明
# makefileall:go build -o httpdemo ./*.golinux:CGO_ENABLED=0 GOOS=linux go build -o httpdemo ./*.gocompile:sudo docker run --rm -v $(shell pwd):/usr/src/httpdemo -w usr/src/httpdemo golang:1.13 go build -tags netgo -o httpdemobuild:sudo docker build -t "3072tech/httpdemo" .compile-build:sudo docker build -t "3072tech/httpdemo" -f Dockerfile2 .
构建镜像
这里用了空scratch做基础镜像,能够最大化节省镜像空间,也体现了golang在docker化方面的优势
# dockerfileFROM scratchWORKDIR /home/service/COPY ./httpdemo ./EXPOSE 8888ENTRYPOINT ["./httpdemo"]
可以将编译和构建放在一个dockerfile文件里头一起实现,如下:
# dockerfile2FROM golang:1.13 AS builderWORKDIR /home/service/COPY . .RUN CGO_ENABLED=0 GOOS=linux go build -tags netgo -o httpdemoFROM scratchWORKDIR /home/service/COPY --from=builder home/service/httpdemo ./EXPOSE 8888ENTRYPOINT ["./httpdemo"]
注:笔者已经将该demo镜像推送到docker hub,可以直接通过docker pull 3072tech/httpdemo拉取。
通过Pod跑起来
这里假设大家已经有一套可用的k8s环境(如何搭建k8s环境请自己google),我们先从最简单的pod进行应用的部署,pod是k8s运行应用的最小单位,容器被放在pod中运行。pod资源文件的描述如下:
# httpdemo-pod.yamlapiVersion: v1kind: Podmetadata:name: httpdemospec:containers:- image: 3072tech/httpdemoname: httpdemoports:- containerPort: 8888protocol: TCP
让pod跑起来 kubectrl create -f ./httpdemo-pod.yaml


通过ReplicationController跑起来
k8s通过各种controller来管理资源,之前创建的pod如果挂掉了则服务不可用,这里通过ReplicationController对pod副本进行管理,比如这里保证以上pod的副本保持在3个。
# httpdemo-rc.yamlapiVersion: v1kind: ReplicationControllermetadata:name: httpdemospec:replicas: 3template:metadata:labels:app: httpdemospec:containers:- name: httpdemoimage: 3072tech/httpdemoports:- containerPort: 8888


注:新版本推荐用ReplicaSet,而不是ReplicationController;实际生产环境一般用Deployment便于服务升级,而不是直接rs或rc。
通过Service和Dns访问
前面我们通过访问pod的ip来调用http接口,但pod是不可靠的,可能重启或者挂掉,通过pod ip访问不可行。这里引入service的概念,通过service可以暴露一个单一不变的IP地址让外部的客户端连接pod。service的资源文件如下:
# httpdemo-svc.yamlapiVersion: v1kind: Servicemetadata:name: httpdemospec:ports:- port: 80targetPort: 8888selector:app: httpdemo


通过service暴露的cluster-ip我们可以用一个虚拟ip来访问到内部的pod,而不会受限于pod ip的变更。但实际生产中直接通过ip进行访问通信也不是很现实,k8s提供了kube-dns模块,可以通过dns对服务进行访问,如下:
[parallels@ks17master k8s]$ kubectl run busybox --rm -it --image=busybox /bin/shIf you don't see a command prompt, try pressing enter./ # wget http://httpdemoConnecting to httpdemo (10.104.144.146:80)saving to 'index.html'index.html 100% |********************************************************************************************************************************************************************************************************************************| 10 0:00:00 ETA'index.html' saved/ # cat index.htmlhello k8s
总结
本文通过一个简单的demo演示了如何通过k8s来搭建应用,但这里并没有涉及到实际使用的方方面面,比如升级和回滚、比如服务探测、自动扩容缩容等,后面会考虑进一步深入探讨。读者也可以自己查找资料学习,推荐《kubernets in action》这本书,已经有中文版。




