1、滚动更新
//创建目录,编写一个简单的Dockerfile
[root@master ~]# mkdir /apache
[root@master ~]# vi /apache/Dockerfile
[root@master ~]# cat /apache/Dockerfile
FROM busybox
RUN mkdir /data && \
echo "Hi xixi,This is test1" > /data/index.html
ENTRYPOINT ["/bin/httpd","-f","-h","/data"]
[root@master ~]#
[root@master ~]# docker build -t caiaoc/httpd:v1 /apache
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM busybox
latest: Pulling from library/busybox
3cb635b06aa2: Pull complete
Digest: sha256:b5cfd4befc119a590ca1a81d6bb0fa1fb19f1fbebd0397f25fae164abe1e8a6a
Status: Downloaded newer image for busybox:latest
---> ffe9d497c324
Step 2/3 : RUN mkdir /data && echo "Hi xixi,This is test" > /data/index.html
---> Running in 17747188e814
Removing intermediate container 17747188e814
---> ffcea89dcadb
Step 3/3 : ENTRYPOINT ["/bin/httpd","-f","-h","/data"]
---> Running in 069e558fc73e
Removing intermediate container 069e558fc73e
---> 30ee750ec176
Successfully built 30ee750ec176
Successfully tagged caiaoc/httpd:v1
// 修改Dockerfile中的访问页面
[root@master ~]# cat /apache/Dockerfile
FROM busybox
RUN mkdir /data && \
echo "Hi haha,This is test2" > /data/index.html
ENTRYPOINT ["/bin/httpd","-f","-h","/data"]
[root@master ~]# docker build -t caiaoc/httpd:v2 /apache
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM busybox
---> ffe9d497c324
Step 2/3 : RUN mkdir /data && echo "Hi haha,This is test2" > /data/index.html
---> Running in 465f47b42955
Removing intermediate container 465f47b42955
---> 5e488463c3ba
Step 3/3 : ENTRYPOINT ["/bin/httpd","-f","-h","/data"]
---> Running in 294fc672d9b7
Removing intermediate container 294fc672d9b7
---> 9edc36bb3eb6
Successfully built 9edc36bb3eb6
Successfully tagged apache/httpd:v2
[root@master ~]#
// 登录 docker.hub仓库,上传镜像当 docker.hub仓库
[root@master ~]# docker push caiaoc/httpd:v1
The push refers to repository [docker.io/caiaoc/httpd]
51d3572108ef: Pushed
64cac9eaf0da: Mounted from library/busybox
v1: digest: sha256:a10fbb0660c236671feb3f18543483dc1eafb06f364d907ed0bba2371ae25866 size: 734
[root@master ~]# docker push caiaoc/httpd:v2
The push refers to repository [docker.io/caiaoc/httpd]
56c5d5a3918d: Pushed
64cac9eaf0da: Layer already exists
v2: digest: sha256:3bcae1aa8f8333fa56eb0474d7e24e2119522b27b8e415ddabddc52249dc1544 size: 734
[root@master ~]#
// 创建3个httpd容器,使用v1版本
[root@master ~]# kubectl create deployment httpd --image caiaoc/httpd:v1 --replicas 3
deployment.apps/httpd created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpd-9cb9f8cb-44dpz 1/1 Running 0 5s
httpd-9cb9f8cb-9twr9 1/1 Running 0 5s
httpd-9cb9f8cb-drhnr 1/1 Running 0 5s
// 暴露端口
[root@master ~]# kubectl expose deployment httpd --port 80 --target-port 80
service/httpd exposed
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd ClusterIP 10.101.203.64 <none> 80/TCP 9s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d21h
nginx NodePort 10.109.48.237 <none> 80:31253/TCP 2d21h
[root@master ~]#
//访问测试
[root@master ~]# curl 10.101.203.64
Hi xixi,This is test1
[root@master ~]#
//写一个死循环
[root@master ~]# while :;do curl 10.101.203.64;done
Hi xixi,This is test1
Hi xixi,This is test1
Hi xixi,This is test1
Hi xixi,This is test1
//升级版本
[root@master ~]# kubectl set image deployment/httpd httpd=caiaoc/httpd:v2
deployment.apps/httpd image updated
[root@master ~]#
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpd-656d6d5c6f-5lmbl 1/1 Running 0 13s
httpd-656d6d5c6f-8dmdh 1/1 Running 0 46s
httpd-656d6d5c6f-ggdzv 0/1 ContainerCreating 0 11s
httpd-9cb9f8cb-44dpz 1/1 Terminating 0 8m32s
httpd-9cb9f8cb-9twr9 1/1 Terminating 0 8m32s
httpd-9cb9f8cb-drhnr 1/1 Running 0 8m32s
[root@master ~]#
//升级完成
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpd-656d6d5c6f-5lmbl 1/1 Running 0 58s
httpd-656d6d5c6f-8dmdh 1/1 Running 0 91s
httpd-656d6d5c6f-ggdzv 1/1 Running 0 56s
httpd-9cb9f8cb-44dpz 0/1 Terminating 0 9m17s
httpd-9cb9f8cb-9twr9 0/1 Terminating 0 9m17s
httpd-9cb9f8cb-drhnr 0/1 Terminating 0 9m17s
[root@master ~]#
[root@master ~]# while :;do curl 10.101.203.64;done
Hi haha,This is test2
Hi haha,This is test2
Hi haha,This is test2
Hi haha,This is test2
Hi haha,This is test2
......
2. 回滚
// 回滚j就是返回到上一个版本
[root@master ~]# kubectl rollout undo deployment/httpd
deployment.apps/httpd rolled back
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpd-656d6d5c6f-5lmbl 1/1 Terminating 0 2m55s
httpd-656d6d5c6f-8dmdh 1/1 Terminating 0 3m28s
httpd-656d6d5c6f-ggdzv 1/1 Terminating 0 2m53s
httpd-9cb9f8cb-ktxfq 1/1 Running 0 5s
httpd-9cb9f8cb-t6qgf 1/1 Running 0 4s
httpd-9cb9f8cb-v4pwh 1/1 Running 0 6s
//此时再访问就又变成v1版本了
[root@master ~]# curl 10.101.203.64
Hi xixi,This is test1
[root@master ~]#
//而再次回滚就会重新变成v2版本,回滚也就是会一直返回到上一个版本
[root@master ~]# kubectl rollout undo deployment/httpd
deployment.apps/httpd rolled back
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpd-656d6d5c6f-2mt8v 0/1 ContainerCreating 0 0s
httpd-656d6d5c6f-jdlbw 1/1 Running 0 3s
httpd-656d6d5c6f-zcnx8 1/1 Running 0 1s
httpd-9cb9f8cb-ktxfq 1/1 Terminating 0 2m37s
httpd-9cb9f8cb-t6qgf 1/1 Running 0 2m36s
httpd-9cb9f8cb-v4pwh 1/1 Terminating 0 2m38s
[root@master ~]# curl 10.101.203.64
Hi haha,This is test2
[root@master ~]#
3、使用yaml(yml)文件创建、删除容器
k8s是一个容器编排引擎,使用YAML文件编排要部署应用,因此在学习之前,应先了解YAML语法格式:
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许使用Tal键,只允许使用空格
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
- ”#” 表示注释,从这个字符一直到行尾,都会被解析器忽略
- YAML只有两种结构类型需要知道: lists, maps
命令参数:
参数名 | 字段类型 | 注释 |
---|---|---|
version | String | 这里是指的是K8S API的版本,默认系统写法是v1,可以用kubectl api-versions命令查询 |
Kind | String | 这里指的是yaml文件定义的资源类型和角色,比如:Pod |
metadata | Object | 元数据对象,固定值就写metadata |
metadata.name | String | 元数据对象的名字,这里由我们编写,比如命名Pod的名字 |
metadata.namespace | String | 元数据对象的命名空间,由我们自身定义 |
Spec | list | 详细定义对象,固定值就写Spec |
spec.containers[] | Object | 这里是Spec对象的容器列表定义,是个列表 |
spec.containers[].name | String | 这里定义容器的名字 |
spec.containers[].image | String | 这里定义要用到的镜像名称 |
当你不知道命令怎么编写的时候使用 explain查看注释
下面这个就是查看 metadata的注释
Pod容器的字段拼写
kubectl + explain + 类型 + 对象命令
kubectl + explain + 类型 + 对象命令 + 对象命令分类
// 查看 metadata使用方式
[root@master ~]# kubectl explain deployment.metadata
// 查看 metadata对象的namespace的使用方式
[root@master ~]# kubectl explain deployment.metadata.namespace
// 列表对象开头必须添加 "-"
<[]Object>
将你需要创建的资源描述到YAML文件中
-
部署:kubectl apply -f xxx.yaml
-
卸载:kubectl delete -f xxx.yaml
示例
// 编写 deployment类型的 yaml文件
[root@master manifest]# vi deploy.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 3
selector: #选择
matchLabels: #匹配标签
app: amu
template: #模板
metadata: #元数据
labels: #标签
app: amu
spec:
containers:
- image: caiaoc/httpd:v1 #容器对象
imagePullPolicy: IfNotPresent #镜像拉取策略
name: httpd
等同于命令:
kubectl create deployment web --image=caiaoc/httpd:v1--replicas=3 -n default
[root@master manifest]# vi svc-deploy.yaml
apiVersion: v1
kind: Service
metadata:
name: web
namespace: default
spec:
ports:
- port: 8001
protocol: TCP #协议
targetPort: 80
selector:
app: amu
type: NodePort #类型
等同于命令
kubectl expose deployment web --port=8001 --target-port=80
//创建pod测试
[root@master manifest]# kubectl create -f deploy.yml
deployment.apps/web created
service/web created
[root@master manifest]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-8576bf4c75-dwgvr 1/1 Running 0 7s
web-8576bf4c75-gnnhr 1/1 Running 0 7s
web-8576bf4c75-mpr2t 1/1 Running 0 7s
[root@master manifest]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d22h
web NodePort 10.97.169.78 <none> 8080:30752/TCP 11s
[root@master manifest]#
[root@master manifest]# curl 10.97.169.78:8080
Hi xixi,This is test1
[root@master manifest]#
5 通过资源定义方式创建一个haproxy的pod进行负载均衡
重启策略:
-
Always:当容器终止退出后,总是重启容器,默认策略。
-
OnFailure:当容器异常退出(退出状态码非0)时,才重启容器。
-
Never:当容器终止退出,从不重启容器。
健康检查类型:
-
livenessProbe (存活检查)∶如果检查失败,将杀死容器,根据Pod的restartPolicy来操作。
-
readinessProbe (就绪检查)︰如果检查失败,Kubernetes会把Podservice endpoints中剔除。
支持的检查方法:
- httpGet:发送HTTP请求,返回200-400范围状态码为成功。
- exec:执行Shell命令返回状态码是0为成功。
- tcpSocket:发起TCP Socket建立成功。
初始化容器
InitContainer:顾名思义,用于初始化工作,执行完就结束,可以理解为一次性任务
- 支持大部分应用容器配置,但不支持健康检查
- 优先应用容器执行
- 应用场景:
- 环境检查:例如确保应用容器依赖的服务启动后再启动应用容器。初始化配置:例如给应用容器准备配置文件
先简单的做出两个运行httpd程序的pod,其中默认的index.html文件不一样
//httpd1
[root@master httpd1]# vim Dockerfile
FROM busybox
RUN mkdir /data && \
echo 'Hi xixi,This is test1' > /data/index.html
CMD ["/bin/httpd","-f","-h","/data"]
[root@master httpd1]# docker build -t 93quan/httpd1:latest .
//httpd2
[root@master httpd2]# vim Dockerfile
FROM busybox
RUN mkdir /data && \
echo 'Hi haha,This is test2' > /data/index.html
CMD ["/bin/httpd","-f","-h","/data"]
[root@master httpd2]# docker build -t 93quan/httpd2:latest .
yaml文件编写
httpd1
[root@master mainfest]# vim httpd1.yaml
---
[root@master manifest]# cat httpd1.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: httpd1
name: httpd1
spec:
replicas: 1
selector:
matchLabels:
app: httpd1
template:
metadata:
labels:
app: httpd1
spec:
containers:
- image: caiaoc/httpd1:v1
imagePullPolicy: IfNotPresent
name: httpd1
---
apiVersion: v1
kind: Service
metadata:
name: httpd1
spec:
ports:
- port: 80
targetPort: 80
selector:
app: httpd1
[root@master mainfest]# kubectl create -f httpd1.yaml
//httpd2
[root@master manifest]# cat httpd2.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: httpd2
name: httpd2
spec:
replicas: 1
selector:
matchLabels:
app: httpd2
template:
metadata:
labels:
app: httpd2
spec:
containers:
- image: caiaoc/httpd2:v1
imagePullPolicy: IfNotPresent
name: httpd2
---
apiVersion: v1
kind: Service
metadata:
name: httpd2
spec:
ports:
- port: 80
targetPort: 80
selector:
app: httpd2
[root@master mainfest]# kubectl create -f httpd2.yaml
查看创建好的资源
[root@master manifest]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpd1-75fc74874f-ghtdw 1/1 Running 0 9m14s
httpd2-cd7486cc8-gsgsz 1/1 Running 0 6m25s
[root@master manifest]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd1 ClusterIP 10.105.138.61 <none> 80/TCP 9m17s
httpd2 ClusterIP 10.99.12.92 <none> 80/TCP 6m28s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d
[root@master manifest]#
haproxy.yml编写
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: haproxy
name: haproxy
spec:
restartPolicy: OnFailure
initContainers:
- name: cfgfile
volumeMounts:
- name: haproxyconfigfile
mountPath: /tmp
containers:
- image: caiaoc/haproxy:v1
imagePullPolicy: IfNotPresent
name: haproxy
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 30
periodSeconds: 10
env:
- name: RSIP
value: "httpd1 httpd2"
---
apiVersion: v1
kind: Service
metadata:
name: haproxy
spec:
ports:
- port: 80
targetPort: 80
selector:
app: haproxy
type: NodePort
访问测试
[root@master manifest]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod/haproxy-7bc53bd789-vhkpw 1/1 Running 0 8m27s
pod/httpd1-75fc74874f-ghtdw 1/1 Running 0 9m14s
pod/httpd2-cd7486cc8-gsgsz 1/1 Running 0 6m25s
[root@master manifest]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/haproxy NodePort 10.97.134.83 <none> 80:31843/TCP 7m48s
service/httpd1 ClusterIP 10.105.138.61 <none> 80/TCP 9m17s
service/httpd2 ClusterIP 10.99.12.92 <none> 80/TCP 6m28s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d
[root@master mainfest]# curl 10.97.134.83:31843
Hi xixi,This is test1
[root@master mainfest]# curl 10.97.134.83:31843
Hi haha,This is test2