使用Kubernetes管理Docker集群
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx\-server
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
\- name: nginx
image: nginx:1.13\-alpine
ports:
\- containerPort: 80
该文件包含了定义一个部署所需的所有必要信息,包括要使用的Docker镜像、副本数量以及容器端口。要了解关于配置部署的更多信息,请参阅官方文档。
2.创建您的第一个部署:
kubectl create \-f nginx.yaml \--record
3.查看部署列表:
kubectl get deployments
NAME DESIRED CURRENT UP\-TO\-DATE AVAILABLE AGE
nginx\-server 1 1 1 1 13s
4.检查Pod状态:
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx\-server\-b9bc6c6b5\-d2gqv 1/1 Running 0 58s
5.要查看部署的创建节点,请添加-o wide
参数:
kubectl get pods \-o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx\-server\-b9bc6c6b5\-d2gqv 1/1 Running 0 1m 192.168.255.197 kube\-worker\-02
扩展部署
Kubernetes可以轻松扩展部署以添加或删除副本。
1.将副本的数量增加到8:
kubectl scale deployment nginx\-server \--replicas\=8
2.检查新副本的可用性:
kubectl get pods \-o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx\-server\-b9bc6c6b5\-4mdf6 1/1 Running 0 41s 192.168.180.10 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-8mvrd 1/1 Running 0 3m 192.168.180.9 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-b99pt 1/1 Running 0 40s 192.168.180.12 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-fjg2c 1/1 Running 0 40s 192.168.127.12 kube\-worker\-2
nginx\-server\-b9bc6c6b5\-kgdq5 1/1 Running 0 41s 192.168.127.11 kube\-worker\-2
nginx\-server\-b9bc6c6b5\-mhb7s 1/1 Running 0 40s 192.168.180.11 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-rlf9w 1/1 Running 0 41s 192.168.127.10 kube\-worker\-2
nginx\-server\-b9bc6c6b5\-scwgj 1/1 Running 0 40s 192.168.127.13 kube\-worker\-2
3.可以使用同样的命令减少副本的数量:
kubectl scale deployment nginx\-server \--replicas\=3
滚动更新
通过部署来管理Pod允许您使用滚动更新(Rolling Upgrades)的功能。滚动更新是一种允许您在不停机的情况下更新应用程序版本的机制。Kubernetes确保至少有25%的Pod可随时提供服务,并会在删除旧Pod之前先创建新的Pod。
1.将容器的NGINX版本从 1.13 升级到 1.13.8:
kubectl set image deployment/nginx\-server nginx\=nginx:1.13.8\-alpine
与扩展过程类似,set
命令使用声明性方法:您只需指定所需的目标状态,控制器会管理完成该目标所需的所有任务。
2.检查更新状态:
kubectl rollout status deployment/nginx\-server
Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 1 old replicas are pending termination...
deployment "nginx-server" successfully rolled out
3.你可以使用describe
命令手动检查应用程序版本:
kubectl describe pod <pod\-name\>
4.如果发生错误,回滚(Rollout)将被挂起,系统将强制要求用户输入 CTRL + C 以取消更新。通过设置无效的NGINX版本来测试:
kubectl set image deployment/nginx\-server nginx\=nginx:1.18.
5.查看当前Pod状态:
kubectl get pods \-o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx\-server\-76976d4555\-7nv6z 1/1 Running 0 3m 192.168.127.15 kube\-worker\-2
nginx\-server\-76976d4555\-wg785 1/1 Running 0 3m 192.168.180.13 kube\-worker\-1
nginx\-server\-76976d4555\-ws4vf 1/1 Running 0 3m 192.168.127.14 kube\-worker\-2
nginx\-server\-7ddd985dd6\-mpn9h 0/1 ImagePullBackOff 0 2m 192.168.180.16 kube\-worker\-1
可以看到名为nginx-server-7ddd985dd6-mpn9h
的Pod正在试图将NGINX更新到一个不存在的版本。
6.检查此Pod以获取该错误的更多详细信息:
kubectl describe pod nginx\-server\-7ddd985dd6\-mpn9h
7.由于在创建部署时使用了--record
参数,您可以通过以下命令检索完整的历史记录:
kubectl rollout history deployment/nginx\-server
REVISION CHANGE\-CAUSE
1 kubectl scale deployment nginx\-server \--replicas\=3
2 kubectl set image deployment/nginx\-server nginx\=nginx:1.13.8\-alpine
3 kubectl set image deployment/nginx\-server nginx\=nginx:1.18
8.您可以使用undo
命令回滚到之前的工作版本:
kubectl rollout undo deployment/nginx\-server
9.要回滚到特定的版本,请使用--to-revision
选项以指定要回滚的目标版本:
kubectl rollout undo deployment/nginx\-server \--to\-revision\=1
Kubernetes服务
您现在已经有了一个运行三个Pod的部署,每个Pod都运行了一个NGINX应用。要将Pod发布到互联网,您需要创建一个 服务。在Kubernetes中,服务是一种抽象,允许随时访问Pod。服务会自动处理IP更改,更新以及扩展,因此在启用该服务后,只要运行的Pod保持活动状态,就可通过互联网访问您的应用程序。
1.配置一个测试服务。
~/nginx-service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: nginx\-service
labels:
run: nginx
spec:
type: NodePort
ports:
\- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: nginx
2.创建服务:
kubectl create \-f nginx\-service.yaml
3.检查新服务的状态:
kubectl get services
NAME TYPE CLUSTER\-IP EXTERNAL\-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none\> 443/TCP 2d
nginx\-service NodePort 10.97.41.31 <none\> 80:31738/TCP 38m
服务正在运行并接受31738
端口上的连接。
4.测试服务:
curl <MASTER\_LINODE\_PUBLIC\_IP\_ADDRESS\>:<PORT(S)\>
5.使用describe
命令查看此服务的其他信息:
kubectl describe service nginx\-service
Name: nginx\-service
Namespace: default
Labels: run\=nginx
Annotations: <none\>
Selector: app\=nginx
Type: NodePort
IP: 10.97.41.31
Port: http 80/TCP
TargetPort: 80/TCP
NodePort: http 31738/TCP
Endpoints: 192.168.127.14:80,192.168.127.15:80,192.168.180.13:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none\>
Kubernetes命名空间
命名空间是是一个逻辑环境,可以灵活的在多个团队或用户之间划分集群资源。
1.查看可用的命名空间:
kubectl get namespaces
default Active 7h
kube\-public Active 7h
kube\-system Active 7h
顾名思义,如果未指定其他的命名空间,则您的部署将会放置在default
命名空间下。kube-system
为Kubernetes创建的对象保留,而kube-public
则对所有用户可用。命名空间可以通过.json
文件创建,也可以直接在命令行创建。
2.为 development 环境新建名为dev-namespace.json
的文件。
~/home/dev-namespace.json
:
{
"kind": "Namespace",
"apiVersion": "v1",
"metadata": {
"name": "development",
"labels": {
"name": "development"
}
}
}
3.在集群中创建命名空间:
kubectl create \-f dev\-namespace.json
4.再次查看命名空间:
kubectl get namespaces
上下文
要使用命名空间,您需要定义使用命名空间的 上下文(Context)。Kubernetes上下文保存在kubectl
配置文件中。
1.查看当前的配置:
kubectl config view
2.检查您当前正在使用的上下文:
kubectl config current\-context
3.使用以下命令添加dev
上下文:
kubectl config set\-context dev \--namespace\=development \\
\--cluster\=kubernetes \\
\--user\=kubernetes\-admin
4.切换至dev
上下文/命名空间:
kubectl config use\-context dev
5.验证更改是否生效:
kubectl config current\-context
6.查看新的配置:
kubectl config view
7.命名空间中的Pod对其他命名空间不可见。列出您的Pod来检查该特性:
kubectl get pods
系统提示“No resources found”,是因为您未在此命名空间中创建Pod或部署,不过您仍然可以添加--all-namespaces
参数来查看这些对象:
kubectl get services \--all\-namespaces
标签
Kubernetes中的任何对象都可以添加标签。标签是一组键值对,可以帮助用户基于各种特征更加轻松的组织、过滤并选择对象。
1.在此命名空间中创建一个测试部署,此部署将包含nginx
标签。
~/my-app.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my\-app
labels:
app: my\-app
spec:
replicas: 4
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
\- name: nginx
image: nginx:1.12\-alpine
ports:
\- containerPort: 80
2.创建部署:
kubectl create \-f my\-app.yaml \--record
3.如果您只需在集群中查找特定的Pod,而不是列出所有Pod,那么在命令中添加-l
选项以按标签搜索通常更有效率:
kubectl get pods \--all\-namespaces \-l app\=nginx
这里仅列出了default
和development
命名空间中的Pod,因为它们的定义中包含nginx
标签。
Kubernetes节点
Kubernetes节点可以是物理机或虚拟机。可以将节点视为Kubernetes抽象模型中的最高级别。
1.列出您当前的节点:
kubectl get nodes
NAME STATUS ROLES AGE VERSION
kube\-master Ready master 21h v1.9.2
kube\-worker\-1 Ready <none\> 19h v1.9.2
kube\-worker\-2 Ready <none\> 17h v1.9.2
2.要查看更多信息,添加-o
参数:
kubectl get nodes \-o wide
3.显示的信息大部分是自解释的,对于检查全部节点是否准备就绪而言非常有用。您可以使用describe
命令以获取特定节点的详细信息:
kubectl describe node kube\-worker\-1
节点维护
Kubernetes提供了一种非常直接的办法使节点安全离线。
1.返回您正在运行NGINX服务的默认命名空间:
kubectl config use\-context kubernetes\-admin@kubernetes
2.检查您的Pod:
kubectl get pods \-o wide
3.在kube-worker-2
节点上禁止新Pod的创建:
kubectl cordon kube\-worker\-2
4.检查您的节点状态:
kubectl get nodes
NAME STATUS ROLES AGE VERSION
kube\-master Ready master 4h v1.9.2
kube\-worker\-1 Ready <none\> 4h v1.9.2
kube\-worker\-2 Ready,SchedulingDisabled <none\> 4h v1.9.2
5.要测试Kubernetes控制器和调度程序,请扩展您的部署:
kubectl scale deployment nginx\-server \--replicas\=10
6.再次查看您的Pod:
kubectl get pods \-o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx\-server\-b9bc6c6b5\-2pnbk 1/1 Running 0 11s 192.168.188.146 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-4cls5 1/1 Running 0 11s 192.168.188.148 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-7nw5m 1/1 Running 0 3d 192.168.255.220 kube\-worker\-2
nginx\-server\-b9bc6c6b5\-7s7w5 1/1 Running 0 44s 192.168.188.143 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-88dvp 1/1 Running 0 11s 192.168.188.145 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-95jgr 1/1 Running 0 3d 192.168.255.221 kube\-worker\-2
nginx\-server\-b9bc6c6b5\-md4qd 1/1 Running 0 3d 192.168.188.139 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-r5krq 1/1 Running 0 11s 192.168.188.144 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-r5nd6 1/1 Running 0 44s 192.168.188.142 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-ztgmr 1/1 Running 0 11s 192.168.188.147 kube\-worker\-1
现在总共有10个Pod,但新Pod只在第一个节点中创建。
7.通知kube-worker-2
节点停止其运行的Pod:
kubectl drain kube\-worker\-2 \--ignore\-daemonsets
node "kube-worker-2" already cordoned
WARNING: Ignoring DaemonSet\-managed pods: calico\-node\-9mgc6, kube\-proxy\-2v8rw
pod "my-app-68845b9f68-wcqsb" evicted
pod "nginx-server-b9bc6c6b5-7nw5m" evicted
pod "nginx-server-b9bc6c6b5-95jgr" evicted
pod "my-app-68845b9f68-n5kpt" evicted
node "kube-worker-2" drained
8.检查上述命令对您Pod产生的效果:
kubectl get pods \-o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx\-server\-b9bc6c6b5\-2pnbk 1/1 Running 0 9m 192.168.188.146 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-4cls5 1/1 Running 0 9m 192.168.188.148 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-6zbv6 1/1 Running 0 3m 192.168.188.152 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-7s7w5 1/1 Running 0 9m 192.168.188.143 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-88dvp 1/1 Running 0 9m 192.168.188.145 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-c2c5c 1/1 Running 0 3m 192.168.188.150 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-md4qd 1/1 Running 0 3d 192.168.188.139 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-r5krq 1/1 Running 0 9m 192.168.188.144 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-r5nd6 1/1 Running 0 9m 192.168.188.142 kube\-worker\-1
nginx\-server\-b9bc6c6b5\-ztgmr 1/1 Running 0 9m 192.168.188.147 kube\-worker\-1
9.您现在已经可以在不中断服务的情况下安全关闭kube-worker-2
节点。
10.完成维护后,通知控制器此节点可以再次进行调度:
kubectl uncordon kube\-worker\-2
参考资料
-
[Manage a Docker Cluster with Kubernetes Linode](https://www.linode.com/docs/applications/containers/manage-a-docker-cluster-with-kubernetes/#kubernetes-namespaces) -
[Kubernetes Handbook Gitbook](https://legacy.gitbook.com/book/rootsongjc/kubernetes-handbook/details) - Kubernetes官方文档
- Calico官方文档