3Windows 安装Kubernetes · SpringCloud微服务实战 · 看云

导航

本节我们介绍下Windows 系统下的Kubernetes环境部署,首先我们都知道,因为一些原因,我们访问不了国外的镜像源。本章主要讲如何在不适用国内的镜像源部署Kubernetes。

系统要求:
1、Windows 10 64位,专业版、企业版、教育版(15063或更高版本)
2、必须启用了Hyper-V和windows 容器特性
硬件要求:
1、支持SLAT(Second Level Address Translation)的64位处理器
2、笔记本内存8G+
3、必须在BIOS中设置启用硬件虚拟化

1. 工具下载

首先需要下载docker-desktop(2.2.0.5 当时最新版的),下载后直接安装即可,全部默认的,直接下一步
https://hub.docker.com/editions/community/docker-ce-desktop-windows
64287868f320088482d17e127a009c27_MD5.png

2. 运行

双击Docker 的图标即可运行,点击可以查看一下运行的版本
点击左下角的有类似鲸鱼的图标->About Docker Desktop
笔者的版本如下,可以看到当前的Kubernetes版本是1.15.5
7c8bb5940cff77d37dd48a8c3f1ea397_MD5.png

3. 配置Docker 的镜像源

点击下图所示的地方
点击左下角的有类似鲸鱼的图标->About Docker Desktop
添加国内的镜像
f1907921474c69b2a03789c511dba49f_MD5.png

具体内容如下

{
  "registry-mirrors": [
    "https://registry.docker-cn.com",
    "https://reg-mirror.qiniu.com",
    "https://hub-mirror.c.163.com",
    "https://docker.mirrors.ustc.edu.cn"
  ],
  "insecure-registries": [],
  "debug": true,
  "experimental": false
}

4. 配置资源大小

因为等下需要部署Kubernetes,所以需要将内存调大一些,至少3g内存
add86a480dc18228d6b85d047b24f8c1_MD5.png

5. Kubernetes部署

勾选如下的配置之后,重启docker-destop
c073b750cc21f1dc97ffdee7e31e3fc7_MD5.png

如果你的笔记本有科学上网工具,等一会Kubernetes就可以起来了

如果没有科学上网,这时候docker-destop因为拉取不了Kubernetes的镜像内容,所以一直显示starting

这里笔者推荐使用docker 单独拉取镜像文件,因为我们之前已经配置了Docker

5.1 Kubernetes 镜像脚本

创建脚本docker-images-k8s.sh文件

并配置以下内容(仅针对Kubernetes 1.15.5版本)

#!/bin/bash

set -e
KUBE_VERSION=v1.15.5
KUBE_DASHBOARD_VERSION=v1.10.1
KUBE_PAUSE_VERSION=3.1
ETCD_VERSION=3.3.10
COREDNS_VERSION=1.3.1
GCR_URL=k8s.gcr.io
ALIYUN_URL=registry.cn-hangzhou.aliyuncs.com/google_containers

# get images
images=(kube-proxy:${KUBE_VERSION}
kube-scheduler:${KUBE_VERSION}
kube-controller-manager:${KUBE_VERSION}
kube-apiserver:${KUBE_VERSION}
pause:${KUBE_PAUSE_VERSION}
etcd:${ETCD_VERSION}
coredns:${COREDNS_VERSION}
kubernetes-dashboard-amd64:${KUBE_DASHBOARD_VERSION})

for imageName in ${images[@]} ; do
docker pull $ALIYUN_URL/$imageName
docker tag $ALIYUN_URL/$imageName $GCR_URL/$imageName
docker rmi $ALIYUN_URL/$imageName
done

docker images

利用Windows PowerShellGit Bash执行docker-images-k8s.sh 脚本,等待执行完重启docker-desktop

./docker-images-k8s.sh

cf975400a9f59acd966d4cd3b444e7ac_MD5.png

5.2 重启docker-desktop

重启之后,等几分钟,可以看到如下图所示的状态
ab33c2cfb12b3f5d888df31d3b0ce64a_MD5.png

5.3 安装Dashboard

同样,科学上网的情况下可以直接通过以下命令启动

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/版本/aio/deploy/recommended.yaml


如果不行的话,笔者提供了一份已经修改好的文件
创建脚本文件 k8s-dashboard.yaml

已经修改好的内容如下
主要修改两个地方
第一个是修改镜像 k8s-dashboard.yaml配置文件113行;
第二个是添加一个type,指定端口类型为 NodePort,这样外界可以通过地址 nodeIP:nodePort 访问 dashboard,k8s-dashboard.yaml配置文件159、163行;

# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# ------------------- Dashboard Secret ------------------- #

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-certs
  namespace: kube-system
type: Opaque

---
# ------------------- Dashboard Service Account ------------------- #

apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system

---
# ------------------- Dashboard Role & Role Binding ------------------- #

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: kubernetes-dashboard-minimal
  namespace: kube-system
rules:
  # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["create"]
  # Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["create"]
  # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
  verbs: ["get", "update", "delete"]
  # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["kubernetes-dashboard-settings"]
  verbs: ["get", "update"]
  # Allow Dashboard to get metrics from heapster.
- apiGroups: [""]
  resources: ["services"]
  resourceNames: ["heapster"]
  verbs: ["proxy"]
- apiGroups: [""]
  resources: ["services/proxy"]
  resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
  verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: kubernetes-dashboard-minimal
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kube-system

---
# ------------------- Dashboard Deployment ------------------- #

kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: kubernetes-dashboard
  template:
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
    spec:
      containers:
      - name: kubernetes-dashboard
        #image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1  修改为我们可以访问到的地址
        image: mirrorgooglecontainers/kubernetes-dashboard-amd64:v1.10.0
        ports:
        - containerPort: 8443
          protocol: TCP
        args:
          - --auto-generate-certificates
          # Uncomment the following line to manually specify Kubernetes API server Host
          # If not specified, Dashboard will attempt to auto discover the API server and connect
          # to it. Uncomment only if the default does not work.
          # - --apiserver-host=http://my-address:port
        volumeMounts:
        - name: kubernetes-dashboard-certs
          mountPath: /certs
          # Create on-disk volume to store exec logs
        - mountPath: /tmp
          name: tmp-volume
        livenessProbe:
          httpGet:
            scheme: HTTPS
            path: /
            port: 8443
          initialDelaySeconds: 30
          timeoutSeconds: 30
      volumes:
      - name: kubernetes-dashboard-certs
        secret:
          secretName: kubernetes-dashboard-certs
      - name: tmp-volume
        emptyDir: {}
      serviceAccountName: kubernetes-dashboard
      # Comment the following tolerations if Dashboard must not be deployed on master
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule

---
# ------------------- Dashboard Service ------------------- #

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  type: NodePort  #增加
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30009 #增加
  selector:
    k8s-app: kubernetes-dashboard

5.4 运行如下命令并运行

kubectl apply -f k8s-dashboard.yaml

5.5 查看dashboard 启动的状态,可以看到启动正常

kubectl get pods -n kube-system |grep dashboard



kubernetes-dashboard-699987dbc9-b4fk4    1/1     Running   1          77m

5.6 访问集群上运行的服务

kubectl get pods,svc -n kube-system


可以看到如下日志,可以看到最后一行有dashboard 的端口30009

$ kubectl get pods,svc -n kube-system
NAME                                         READY   STATUS    RESTARTS   AGE
pod/coredns-5c98db65d4-6qtxz                 1/1     Running   1          87m
pod/coredns-5c98db65d4-dpzml                 1/1     Running   1          87m
pod/etcd-docker-desktop                      1/1     Running   0          86m
pod/kube-apiserver-docker-desktop            1/1     Running   0          86m
pod/kube-controller-manager-docker-desktop   1/1     Running   0          87m
pod/kube-proxy-jmx2z                         1/1     Running   0          87m
pod/kube-scheduler-docker-desktop            1/1     Running   0          86m
pod/kubernetes-dashboard-699987dbc9-b4fk4    1/1     Running   1          78m
pod/storage-provisioner                      1/1     Running   0          86m

NAME                           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
service/kube-dns               ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP   87m
service/kubernetes-dashboard   NodePort    10.98.176.140   <none>        443:30009/TCP            78m


5.7 dashboard 访问

浏览器输入https://127.0.0.1:30009/#!/login,如果访问不了换火狐浏览器访问

注意是https 不是http
3dfdb82ae0076a53c6b4258ecdde8cb1_MD5.png

选择Token,Token的值可以用下面的命令获取:

kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep kubernetes-dashboard | awk '{print $1}')

e425c2a46375c605543a0fae2acdea0b_MD5.png

将token 复制出来即可
0a36762d512ca56d98346bce4b4c320f_MD5.png

登录进来之后,可以看到下图所示
7ac7ac5fa0b7aaecbb752e94ecb98d1c_MD5.png

6. 使用Kubernetes 部署测试

6.1 创建一个Nginx Deployment:

kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort

6.2 使用命令kubectl get pod,svc查看是否正常

NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-554b9c67f9-xp7n7   1/1     Running   0          62m

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        93m
service/nginx        NodePort    10.107.48.78   <none>        80:31225/TCP   62m


通过 kubectl get pods,svc -o wide 可以看到具体的运行的节点,当前只有一个节点docker-desktop

6.3 浏览器验证nginx

我们通过浏览器输入http://127.0.0.1:31225/
65b1ceaadd2851f2517eab6418cb9f4a_MD5.png

通过 docker-desktop 可以看到部署情况
4b8bb00b24e68989c46c51d2e3a5bf63_MD5.png

6.4 删除pod节点

使用kubectl get pods命令查看Pod的情况

192:~ mac$ kubectl get pods
NAME  READY  STATUS RESTARTS  AGE

nginx-554b9c67f9-qcs5w  1/1  Running  0 16m

使用kubectl delete命令删除这个Pod

192:~ mac$ kubectl delete pod nginx-554b9c67f9-qcs5w

pod "nginx-554b9c67f9-qcs5w" deleted

通过命令kubectl get pods看到,一个节点被停止了,又起来了一个,因为默认情况下,replicas的值为1,Kubernetes集群会始终保持Nginx的实例为1

192:~ mac$ kubectl get pods
NAME  READY  STATUS RESTARTS  AGE

nginx-554b9c67f9-2n52x  0/1  ContainerCreating  0 8s

nginx-554b9c67f9-qcs5w  0/1  Terminating  0 18m

可以看出通过kubectl delete删除不行,需要使用kubectl delete deployment来完成
使用kubectl get deployments命令查看当前的deployment


192:~ mac$ kubectl get deployments

NAME READY  UP-TO-DATE  AVAILABLE  AGE

nginx  1/1  1 1  23m

使用命令kubectl delete deployment nginx删除

    
192:~ mac$ kubectl delete deployment nginx

deployment.extensions "nginx" deleted

再使用命令kubectl get deployments查看当前的deployment,可以看到已经被删除了

192:~ mac$ kubectl get deployments

No resources found.

6.5 通过自定义yml 部署

下面我们使用yml的方式创建一个实例的Nginx应用,主要设置replicas为1 ,实际生产使用的时候可以设置多个,比如3个

vim nginx-rc.yml

内容如下所示:

apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx-rc
spec:
  replicas: 1
  selector:
    name: nginx
  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80

创建应用的配置

vim nginx-service.yml

内容如下所示:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  ports:
    - port: 8080
      targetPort: 80
      protocol: TCP
  type: NodePort
  selector:
    name: nginx

接着执行下面这两条命令启动Nginx:

kubectl create -f nginx-rc.yml
kubectl create -f nginx-service.yml

使用kubectl get pods命令查看Pod

192:~ mac$ kubectl get pods

NAME  READY  STATUS RESTARTS  AGE

nginx-rc-pqnqq  1/1  Running  0 18s

使用kubectl get services命令查看Service

192:~ mac$ kubectl get services

NAME TYPE CLUSTER-IP  EXTERNAL-IP  PORT(S) AGE

kubernetes ClusterIP  10.96.0.1  443/TCP 5d23h

nginx  NodePort 10.107.127.200   80:32161/TCP  38m

nginx-service  NodePort 10.103.94.180  8080:30093/TCP  52s

使用kubectl describe svc nginx-service命令查看Nginx Service详情

192:~ mac$ kubectl describe svc nginx-service

Name:  nginx-service

Namespace: default

Labels:  

Annotations: 

Selector:  name=nginx

Type:  NodePort

IP:  10.103.94.180

LoadBalancer Ingress:  localhost

Port:   8080/TCP

TargetPort:  80/TCP

NodePort:   30093/TCP

Endpoints: 10.1.0.18:80

Session Affinity:  None

External Traffic Policy: Cluster

Events:  

使用命令kubectl get pods,svc -o wide查看Nginx Pod具体位于节点

192:~ mac$ kubectl get pods,svc -o wide

NAME  READY  STATUS RESTARTS  AGE  IP NODE  NOMINATED NODE  READINESS GATES

pod/nginx-rc-pqnqq  1/1  Running  0 2m30s  10.1.0.18  docker-desktop    

  

NAME TYPE CLUSTER-IP  EXTERNAL-IP  PORT(S) AGE  SELECTOR

service/kubernetes ClusterIP  10.96.0.1  443/TCP 5d23h  

service/nginx  NodePort 10.107.127.200   80:32161/TCP  40m  app=nginx

service/nginx-service  NodePort 10.103.94.180  8080:30093/TCP  2m22s  name=nginx

浏览器输入http://127.0.0.1:30093/,这个端口是从上面的命令获取到的
65b1ceaadd2851f2517eab6418cb9f4a_MD5.png

删除的话执行下面这两条命令即可:

kubectl delete -f nginx-service.yml
kubectl delete -f nginx-rc.yml