一、准备工作
0. 基本概念
Node
):一个节点是一个运行 Kubernetes 中的主机。Pod
):一个 Pod 对应于由若干容器组成的一个容器组,同个组内的容器共享一个存储卷(volume)。pos-states
):包含所有容器状态集合,包括容器组状态类型,容器组生命周期,事件,重启策略,以及 replication controllers。services
):一个 Kubernetes 服务是容器组逻辑的高级抽象,同时也对外提供访问容器组的策略。volumes
):一个卷就是一个目录,容器对其有访问权限。labels
):标签是用来连接一组对象的,比如容器组。标签可以被用来组织和选择子对象。accessing_the_api
):端口,IP 地址和代理的防火墙规则。ux
):用户可以通过 web 界面操作 Kubernetes。cli
):kubecfg
命令。1. 制作一个镜像
用go写一个简单的httpsvr,代码如下:
package main
import (
"fmt"
"log"
"net/http"
)
func homePage(writer http.ResponseWriter, request *http.Request) {
err := request.ParseForm()
fmt.Fprint(writer, "<html><body>")
if err != nil {
fmt.Fprintf(writer, "%s", err)
}
content, found := request.Form["name"]
if found {
fmt.Fprintf(writer, "%s", content)
}
fmt.Fprint(writer, "</body></html>")
}
func main() {
http.HandleFunc("/", homePage)
err := http.ListenAndServe(":9001", nil)
if err != nil {
log.Fatal("failed to start server", err)
}
}
撰写Dockerfile,这里的scratch表示为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。
# Dockerfile References: https://docs.docker.com/engine/reference/builder/
# Start from golang v1.11 base image
FROM golang:1.11
# Add Maintainer Info
LABEL maintainer="yachang.wang@gmail.com"
# Set the Current Working Directory inside the container
WORKDIR $GOPATH/src/github.com/callicoder/go-docker
# Copy everything from the current directory to the PWD(Present Working Directory) inside the container
COPY . .
# Download all the dependencies
# https://stackoverflow.com/questions/28031603/what-do-three-dots-mean-in-go-command-line-invocations
RUN go get -d -v ./...
# Install the package
RUN go install -v ./...
# This container exposes port 8080 to the outside world
EXPOSE 9001
# Run the executable
ENTRYPOINT ["./http_demo"]
#FROM scratch
FROM golang:1.11
# Copy everything from the current directory to the PWD(Present Working Directory) inside the container
COPY . .
#start
EXPOSE 9001
# Run the executable
ENTRYPOINT ["./http_demo"]
$ docker build -t http_demo:v1 .
Sending build context to Docker daemon 6.572MB
Step 1/3 : FROM scratch
--->
Step 2/3 : EXPOSE 9001
---> Running in e79fcce5b314
Removing intermediate container e79fcce5b314
---> e4318ba62c4f
Step 3/3 : CMD ["./http_demo"]
---> Running in 0b01a5a221f0
Removing intermediate container 0b01a5a221f0
---> 73ba3f4115ec
Successfully built 73ba3f4115ec
Successfully tagged http_demo:v1
build成功后,可以查看已创建。
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
http_demo v1 73ba3f4115ec About an hour ago 0B
2. 创建一个pod
使用kubectl run创建一个deployment。
$ kubectl run http-demo --image=http_demo:v20 --port=9001
deployment.apps "http-demo" created
查看deployment运行状态
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
http-demo 1 1 1 0 43s
查看pod运行状态
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
http-demo-6c95d79fd-5wckb 0/1 ImageInspectError 0 2m
3. 删除pod
$ kubectl delete pod http-demo-6c95d79fd-5wckb
pod "http-demo-6c95d79fd-5wckb" deleted
$ kubectl delete deployment http-demo
deployment.extensions "http-demo" deleted
4. 开启对外开放
上面的webserver监听9001端口,但这时netstant -ant | grep 9001查不到端口监听,原因是默认情况下,pod 只可以在 Kubernetes 群集内部访问,为了使容器可以从 Kubernetes 虚拟网络外访问,你必须用 Kubernetes service 让 pod 对外开放。
$ kubectl expose deployment http-demo --type="LoadBalancer"
service "http-demo" exposed
这时可以进行测试,同时也可以直接用curl访问
$ netstat -ant | grep 9001
tcp6 0 0 ::1.9001 *.* LISTEN
tcp4 0 0 *.9001 *.* LISTEN
也可以查询service.
$ kubectl get services http-demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
http-demo LoadBalancer 10.101.6.223 localhost 9001:30945/TCP 2m
二、扩容与部署
1. Kubernetes 的强大功能之一就是他可以很容易的扩容你的应用程序。假设你突然需要增加你的应用;你只需要告诉deployment
一个新的 pod 副本总数即可:
$ kubectl scale deployment http-demo --replicas=2
deployment.extensions "http-demo" scaled
现在,我们拥有2个应用副本了,每个在集群上独立运行,并能够负载均衡。
$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
http-demo 2 2 2 2 8m
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
http-demo-55cb77556b-fgkl4 1/1 Running 0 9m
http-demo-55cb77556b-x4nn2 1/1 Running 0 1m
2. 滚动更新
下面我们来测试下滚动更新功能,修改下http_demo.go,增加一个输出,构建一个新版本镜像
$ docker build -t http_demo:v22 .
设置并更新到新版本
$ kubectl set image deployment/http-demo http-demo=http_demo:v22
deployment.apps "http-demo" image updated
这次可以查看
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
http-demo 2 2 2 2 2h
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
http-demo-54fcd8d969-lrjnt 1/1 Running 0 1m
http-demo-54fcd8d969-r75f6 1/1 Running 0 1m
可以用curl进行测试输出
$ curl 127.0.0.1:9001
<html><body>This is a new version.</body></html>
三、进阶
1. 使用YAML文件创建,以上面的http_demo:v22镜像为例,创建一个新的deployment
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: http-demo2
spec:
replicas: 3
template:
metadata:
labels:
run: http-demo2
spec:
containers:
- name: http-demo
image: http_demo:v22
ports:
- containerPort: 9001
kubectl create -f ./appgo.yaml
2. 可以通过consle或者webui查看,http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/overview?namespace=default
3. 下面测试下多个容器打到一个pod中
创建两个进程,分别监听9002和9003端口
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: web-demo
spec:
replicas: 3
template:
metadata:
labels:
run: web-demo
spec:
containers:
- name: web-9002
image: web_9002:v1
ports:
- containerPort: 9002
- name: web-9003
image: web-9003:v1
ports:
- containerPort: 9003
创建并暴露端口。
kubectl create -f ./appgo.yaml
kubectl expose deployment web-demo --type="LoadBalancer"
可以查看pods和services
kubectl get pods
NAME READY STATUS RESTARTS AGE
http-demo-c7fff58fb-7ccrl 1/1 Running 0 1d
http-demo-c7fff58fb-kpvp6 1/1 Running 0 1d
web-demo-7b5cdcfd4c-5kcn4 0/2 ImagePullBackOff 0 1m
web-demo-7b5cdcfd4c-ftqft 0/2 ImagePullBackOff 0 1m
web-demo-7b5cdcfd4c-rrg4v 0/2 ImagePullBackOff 0 1m
wangyachangdeMacBook-Pro:appgo wangyachang$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
http-demo LoadBalancer 10.101.6.223 localhost 9001:30945/TCP 1d
http-demo2 LoadBalancer 10.106.186.205 <pending> 9001:31759/TCP 18h
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13d
web-demo LoadBalancer 10.99.58.137 localhost 9002:30649/TCP,9003:31801/TCP 3m
在写yaml文件的时候发现,image必须指定版本号,不能用latest.
4. 测试进程监控和重启
在web-9002和web-9003中,预留了一个控制命令可以使进程退出,这里测试下退出后,查看进程状态,可以看到在不同的pods中有出现重启的情况.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
http-demo-c7fff58fb-7ccrl 1/1 Running 0 1d
http-demo-c7fff58fb-kpvp6 1/1 Running 0 1d
web-demo-cc75bcdd5-5j65n 2/2 Running 1 6m
web-demo-cc75bcdd5-q4wwl 2/2 Running 2 6m
web-demo-cc75bcdd5-ztc26 2/2 Running 0 6m
5. 测试伸缩性
$ kubectl autoscale deployment web-demo --cpu-percent=50 --min=2 --max=5
deployment.apps "web-demo" autoscaled
测试前,先调整部署web-demo为1个,设置后可以查看当前状态和数量,如下所示,正在启动中
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
http-demo-c7fff58fb-7ccrl 1/1 Running 0 1d
http-demo-c7fff58fb-kpvp6 1/1 Running 0 1d
web-demo-cc75bcdd5-df5nq 2/2 Running 0 5h
web-demo-cc75bcdd5-v8n5q 0/2 ContainerCreating 0 1s
TO BE CONTINUE
参考:
https://www.cnblogs.com/miaoying/p/10301125.html - MAC搭建dashboard
http://kubernetes.kansea.com/docs/hellonode/
https://yeasy.gitbooks.io/docker_practice/kubernetes/design.html