【注意】最后更新于 December 11, 2019,文中内容可能已过时,请谨慎使用。
本地快速装一个微型的kubernetes环境, 翻墙的苦谁能懂?
mac 本地安装minikube环境
环境需求:
- kubectl 本地做命令行控制用, 所有的命令操作都是通过它
- vittualBox v5.1 + 更新到最新版本就对了
- minikube 在本地搭建测试环境
翻墙有困难的可以参考一下这个 https://yq.aliyun.com/articles/221687
安装 kubectl
下载最新 minikube
不建议使用brew安装, 首先版本不会是最新, 再者会出现莫名其妙的问题
1
2
3
|
➜ curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 && \
chmod +x minikube && \
sudo mv minikube /usr/local/bin/
|
默认 start 时运行的virtualBox 去官网下个最新的就行
启动, 最好把docker镜像指定到国内
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
➜ ~ minikube start --registry-mirror=https://registry.docker-cn.com
😄 minikube v1.0.1 on darwin (amd64)
💿 Downloading Minikube ISO ...
142.88 MB / 142.88 MB [============================================] 100.00% 0s
🤹 Downloading Kubernetes v1.14.1 images in the background ...
🔥 Creating virtualbox VM (CPUs=2, Memory=2048MB, Disk=20000MB) ...
📶 "minikube" IP address is 192.168.99.103
🐳 Configuring Docker as the container runtime ...
🐳 Version of container runtime is 18.06.3-ce
⌛ Waiting for image downloads to complete ...
✨ Preparing Kubernetes environment ...
💾 Downloading kubeadm v1.14.1
💾 Downloading kubelet v1.14.1
🚜 Pulling images required by Kubernetes v1.14.1 ...
🚀 Launching Kubernetes v1.14.1 using kubeadm ...
⌛ Waiting for pods: apiserver proxy etcd scheduler controller dns
🔑 Configuring cluster permissions ...
🤔 Verifying component health .....
💗 kubectl is now configured to use "minikube"
🏄 Done! Thank you for using minikube!
➜ ~ kubectl cluster-info
Kubernetes master is running at https://192.168.99.103:8443
KubeDNS is running at https://192.168.99.103:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
|
如果Minikube ISO
存在墙的问题, 就把iso下载后放到 ~/.minikube/cache/iso/
下
这时Mac上的docker不能用docker for Mac提供的了, 而是宿主机里面的docker, 切换命令为:
1
|
➜ eval $(minikube docker-env)
|
撤销更改
1
|
➜ eval $(minikube docker-env -u)
|
加载后台控制面板, 稍等一会, 自动打卡后台界面
部署第一个应用
命令行部署
创建node.js 应用
创建文件 server.js
1
2
3
4
5
6
7
8
9
|
var http = require('http');
var handleRequest = function(request, response) {
console.log('Received request for URL: ' + request.url);
response.writeHead(200);
response.end('Hello World! V1');
};
var www = http.createServer(handleRequest);
www.listen(3000);
|
运行
1
|
node server.js // 访问地址 http://localhost:3000
|
创建docker镜像
1
2
3
4
5
6
|
FROM node:8.10.0
EXPOSE 3000
COPY server.js .
CMD ["node", "server.js"]
|
构建镜像
1
|
➜ docker build -t hello-node:v1 .
|
如果出现Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
说明你忘了执行 eval $(minikube docker-env)
kube用的 docker 和你本地用的 docker 是两个位置, kube的在虚拟机里运行
创建 deployment
有了镜像就具备创建pod的条件, 通常来说不用直接创建 pod
, 而是创建 deployment
或者 replication controller
, 由他们来负责管理服务的运行, 规模缩放, 自动重启等等这些操作, 就单个pod
来说是可以随时被销毁的, 不能作为稳定服务的保证
1
2
3
|
➜ kubectl run hello-node --image=hello-node:v1 --port=3000
或
➜ kubectl create deployment hello-node --image=hello-node:v1
|
查看当前deployment
1
2
3
|
➜ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
hello-node 1/1 1 1 8m8s
|
ready 1/1
说明已经准备就绪了
查看 pod
1
2
3
|
➜ hellonode git:(master) ✗ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-node-5c58cb6dd4-h65fx 1/1 Running 0 8m40s
|
从这两条信息就能看出来, 每个pod都是带随机字符串的, 并不打算给人去操作, 我们主要专注在deployment
和 service
的搭建
查看 deployment
描述
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
➜ kubectl describe deployments/hello-node
Name: hello-node
Namespace: default
CreationTimestamp: Mon, 13 May 2019 14:17:03 +0800
Labels: run=hello-node
Annotations: deployment.kubernetes.io/revision: 1
Selector: run=hello-node
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: run=hello-node
Containers:
hello-node:
Image: hello-node:v1
Port: 3000/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: hello-node-5c58cb6dd4 (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set hello-node-5c58cb6dd4 to 1
|
这里是对deployment
的概览, Pod Template:
下就是每个pods的配置, 之后对部署的扩容都是基于这个去复制
到目前为止我们创建了deployment
而且也自动生成pod
了, 可是服务并不能被访问到, 为什么? 因为端口没有对外暴露出来, 所以有了下一步
创建service
service
就是用来对我暴露服务的东西, 所有的 pod
都是在内网通信, 外部访问就得让 service
这层代理去转发过去, --type=LoadBalancer
就是指定转发为负载均衡模式, kubectl create service -h
查看更多, 这里不细讲
创建service
1
2
3
|
➜ kubectl expose deployment hello-node --type=LoadBalancer
或
➜ kubectl expose deployment hello-node --type=LoadBalancer --port=3000 // 这里指定端口
|
查看
1
2
3
4
|
➜ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-node LoadBalancer 10.111.18.151 <pending> 3000:31349/TCP 3s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d
|
详细信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
➜ kubectl describe services hello-node
Name: hello-node
Namespace: default
Labels: run=hello-node
Annotations: <none>
Selector: run=hello-node
Type: LoadBalancer
IP: 10.111.18.151
Port: <unset> 3000/TCP
TargetPort: 3000/TCP
NodePort: <unset> 31349/TCP
Endpoints: 172.17.0.7:3000
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
|
NodePort
就是绑定在节点的那个端口上, 直接访问节点ip就行, 也可以用minikube命令 minikube service hello-node
自动帮你打开本地地址
扩展示例
线上肯定是有这种动态扩容的情况, 而且多实例之间滚动升级也不会停止服务
1
2
3
4
5
6
7
8
|
➜ kubectl scale deployments/hello-node --replicas=4
deployment.extensions/hello-node scaled
➜ hellonode git:(master) ✗ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-node-5c58cb6dd4-d2qq9 1/1 Running 0 18s
hello-node-5c58cb6dd4-h65fx 1/1 Running 0 51m
hello-node-5c58cb6dd4-jlzjw 1/1 Running 0 18s
hello-node-5c58cb6dd4-vmx4f 1/1 Running 0 18s
|
更新应用
重新构建一个node的镜像
service.js
1
2
3
4
5
6
7
8
9
|
var http = require('http');
var handleRequest = function(request, response) {
console.log('Received request for URL: ' + request.url);
response.writeHead(200);
response.end('Hello World! V2');
};
var www = http.createServer(handleRequest);
www.listen(3000);
|
1
|
➜ docker build -t hello-node:v2 .
|
设置 deployment
使用新镜像
1
|
➜ kubectl set image deployment/hello-node hello-node=hello-node:v2
|
查看每个pod的具体情况
1
|
➜ kubectl describe pods
|
再访问刚才的地址就能看到改变了
清除资源
1
2
|
➜ kubectl delete service hello-node
➜ kubectl delete deployments hello-node
|
经过上面一套操作下来, 应该也对k8s有了一个大致的印象了, 毕竟光看实践才是检验真理的唯一标准, 但是如果部署一个服务这样一个命令一个命令的敲是很要命的, 而且服务器这玩意, 轻易不会动, 时间一长就容易忘, 因此用配置文件去启动更加合理
通过 yaml 启动
如下: test-service.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
apiVersion: v1
kind: Service
metadata:
name: test-service
labels:
version: v2
run: hello-node
app: test-service
spec:
type: LoadBalancer
ports:
- port: 3001
targetPort: 3000
protocol: TCP
selector:
app: test-service
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-service
labels:
app: test-service
spec:
replicas: 2
selector:
matchLabels:
app: test-service
template:
metadata:
labels:
app: test-service
spec:
containers:
- name: node-pod
image: hello-node:v2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3000
|
执行
1
2
|
➜ kubectl create -f test-service.yaml
➜ minikube service test-service
|
这样通过配置文件就能启动了, 配置文件里里的字段后续我们再详细的讲一下
删除 kubectl delete -f test-service.yaml
代码地址
相关资料
文章作者
GPF
上次更新
2019-12-11
(793782b)