Go to my github

.NET Core on K8S快速入门课程--学习笔记

课程链接:http://video.jessetalk.cn/course/explore

良心课程,大家一起来学习哈!

目录

  • 01-介绍K8s是什么
  • 02-为什么要学习k8s
  • 03-如何学习k8s
  • 04-K8S集群基本概念
  • 05-安装本地k8s单节点集群
  • 06-K8S三大核心组件介绍
  • 07-Service的三种类型及Dashboad部署
  • 08-kubectl工具命令介绍
  • 09-yaml部署文件格式介绍
  • 10-部署netcore api到K8S
  • 11-k8s高可用集群介绍
  • 12-进阶介绍

01-介绍K8s是什么

Docker VS VirtualMachine

  • 敏捷地应用创建和部署
  • 持续开发,集成和部署
  • 开发和运行相分离
  • 开发,测试和生产环境的持续
  • 云和操作系统版本的可移植性,可以运行在 Ubuntu, RHEL, CoreOS, on-prem, Google Container Engine,和任何其它的运行环境中。
  • 松耦合,分布式,弹性,自由的微服务
  • 资源隔离:可以预测的应用性能
  • 资源使用:高效

Docker 容器集群

镜像 => run => 容器(运行时)

  • 同一个容器在同一台Host上能部署几份?
  • 如果实现在多台机器上快速部署?
  • 不同容器在不同机器上如何交互?如何做负载均衡?

K8S 介绍

一个用于容器集群的自动化部署、扩容以及运维的开源平台

  • 快速而有预期地部署你的应用
  • 极速地扩展你的应用
  • 无缝对接新的应用功能
  • 节省资源,优化硬件资源的使用

02-为什么要学习k8s

通过 K8S 降低整个基础设施在架构和运维上的难度

测试环境

  • 将多个API打成镜像部署到不同的节点上
  • 通过 Node Port 本地可以直接连到 API 进行测试
  • Mysql 与 API 可以通过 service 连接
  • 一套脚本部署

生产环境

  • Mysql, Redis, 消息队列使用第三方服务(腾讯云)
  • 也可以通过 桥接 将内部 API 与外部服务连接

03-如何学习k8s

掌握学习的方法(刻意练习)

  • 先了解全貌和整体
  • 对整体结构进入拆分、梳理脉络(思维导图)
  • 马上开始行动(比如本地部署一个集群)
  • 在动的过程中逐步加深,每一个阶段有阶段性目标
  • 及时进行回顾与复盘,与理论相结合
  • 输出(学习金字塔)

学习K8S的路径

  • 了解基本概念及核心组件
  • 使用本地单节点集群来学习k8s
  • 用kubectl 与本地集群建立连接
  • 部署服务到 k8s集群
  • 对k8s服务进行扩容、更新
  • 进一步学习k8s资源(pod, deployment, service, statefulset, ingress…)
  • 设计微服务
  • 搭建k8s集群或者使用云服务商的k8s服务
  • 添加持续集成、日志搜集、监控和指标度量、跟踪

04-K8S集群基本概念

Agenda

  • K8S集群基本概念
  • 本地搭建k8s单节点集群
  • POD & Service & Deployment
  • Service 的三种类型
  • Yaml 部署文件语法初体验
  • 初始化一个.NET Core API 并push到docker hub
  • 把.Net Core API 部署到 K8s
  • K8S集群高级概念

K8S集群基本概念

  • 集群(多个机器拼在一起,共同处理)
  • Node (Master:维护集群状态 and Worker:处理)(高可用时架构不同)
  • 资源(内部组件为一个资源,对外暴露 restful 的 WebApi)(例如 Yaml)
  • Kubectl (本地客户端,一个命令行工具,连接到 K8S 集群)

05-安装本地k8s单节点集群

安装教程

Docker社区版中Kubernetes开发

输入国内镜像地址(https://registry.docker-cn.com),才能更好的拿到谷歌开头的镜像

运行下列脚本可以从阿里云镜像服务下载Kubernetes安装所需Docker镜像,您也可以通过修改 images.properties 文件定义自己安装所需的Docker镜像

右键 git bash

git clone https://github.com/AliyunContainerService/k8s-for-docker-desktop
cd k8s-for-docker-desktop

如果您安装版本为18.09/18.06版本可以直接使用master分支;如果是18.03稳定版请使用对应的代码分支 git checkout 18.03

Windows下加载镜像(./load_images.sh)可能会报错

使用 PowerShell 执行 load_images.ps1 循环拉取 images.properties 的镜像

需要开启VPN

在Docker for Mac中开启 Kubernetes

勾选 Enable Kubernetes 安装,等待消息 Kubernetes is running

配置信息路径:C:\Users\MINGSON.kube

测试 kubectl 命令,在左下角 Windows 图标右键启动 Window PowerShell(管理员)

PS C:\WINDOWS\system32> kubectl get nodes
NAME                 STATUS    ROLES     AGE       VERSION
docker-for-desktop   Ready     master    1d        v1.10.3
PS C:\WINDOWS\system32> kubectl get services
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   1d

06-K8S三大核心组件介绍

POD & Service

POD: K8S 运行时最小单元逻辑(类似docker里面的容器)

与容器的区别:

docker里面每个容器只有一个主进程挂载,可以使用supervisord同时让两个进程运行起来,可是docker只有一个入口,所以只能把supervisord暴露成入口,这种情况API很难进入到里面每个进程

POD里面可以运行多个容器,同时容器之间的挂载可以共享

docker映射端口后可以直接访问

POD必须挂载一个service(对外暴露POD),之后POD才可以在集群外部被访问

学习资料

Kubernetes中的Pod的到底是什么?

名词解释 Pods

deployment

kind:声明k8s资源固定的模板
replicas:POD实例,复本
containers:容器(数组形式,可以定义多个容器)
image:镜像

一个deployment的POD里面可以运行多个容器

07-Service的三种类型及Dashboad部署

  • ClusterIP
  • NodePort
  • LoadBalancer

学习资料

Kubernetes的三种外部访问方式:NodePort、LoadBalancer 和 Ingress

ClusterIP 服务是 Kubernetes 的默认服务。它给你一个集群内的服务,集群内的其它应用都可以访问该服务。集群外部无法访问它。

ClusterIP 服务的 YAML 文件类中 type: ClusterIP(不填写默认也是ClusterIP)

NodePort 服务是引导外部流量到你的服务的最原始方式。NodePort,正如这个名字所示,在所有节点(虚拟机)上开放一个特定端口,任何发送到该端口的流量都被转发到对应服务。

NodePort 服务的 YAML 文件类中 type: NodePort,需要指定一个端口 nodePort: 30036

NodePort 是开发环境中最常用的类型

LoadBalancer 服务是暴露服务到 internet 的标准方式。在 GKE 上,这种方式会启动一个 Network Load Balancer,它将给你一个单独的 IP 地址,转发所有流量到你的服务。

LoadBalancer 主要是云服务商使用

使用 kubectl 连接本地集群,部署 dashboard(脚本中通过 ClusterIP,需要使用代理的模式)

在左下角 Windows 图标右键启动 Window PowerShell(管理员)

PS C:\WINDOWS\system32> kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
secret "kubernetes-dashboard-certs" created
serviceaccount "kubernetes-dashboard" created
role.rbac.authorization.k8s.io "kubernetes-dashboard-minimal" created
rolebinding.rbac.authorization.k8s.io "kubernetes-dashboard-minimal" created
deployment.apps "kubernetes-dashboard" created
service "kubernetes-dashboard" created

脚本中的 namespace: kube-system 是一个资源,可以通过 kubectl 命令行获取

PS C:\WINDOWS\system32> kubectl get namespace
NAME          STATUS    AGE
default       Active    1d
docker        Active    1d
kube-public   Active    1d
kube-system   Active    1d
PS C:\WINDOWS\system32> kubectl get deploy -n kube-system
NAME                   DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kube-dns               1         1         1            1           1d
kubernetes-dashboard   1         1         1            1           2m
PS C:\WINDOWS\system32> kubectl get service -n kube-system
NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
kube-dns               ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP   1d
kubernetes-dashboard   ClusterIP   10.106.79.145   <none>        443/TCP         2m

开启API Server的本地监听端口,之后就可以打开控制台

PS C:\WINDOWS\system32> kubectl proxy
Starting to serve on 127.0.0.1:8001

浏览器访问:
http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/overview?namespace=default

跳过

切换命名空间到 kube-system

容器组里运行的 dashboard

通过 NodePort 部署

在本地新建一个文件 kubernetes-dashboard.yaml,将脚本(https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml)内容保存到本地文件 kubernetes-dashboard.yaml

添加 type: NodePort,nodePort: 30065(端口必须在30000-32767)

# ------------------- 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: 30065
  selector:
    k8s-app: kubernetes-dashboard

删除上面部署的 deploy

PS C:\WINDOWS\system32> kubectl get deploy -n kube-system
NAME                   DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kube-dns               1         1         1            1           1d
kubernetes-dashboard   1         1         1            1           52m
PS C:\WINDOWS\system32> kubectl delete deploy kubernetes-dashboard -n kube-system
deployment.extensions "kubernetes-dashboard" deleted

删除服务,使用缩写svc

PS C:\WINDOWS\system32> kubectl get svc -n kube-system
NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
kube-dns               ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP   1d
kubernetes-dashboard   ClusterIP   10.106.79.145   <none>        443/TCP         53m
PS C:\WINDOWS\system32> kubectl delete svc kubernetes-dashboard -n kube-system
service "kubernetes-dashboard" deleted

再次启动代理

PS C:\WINDOWS\system32> kubectl proxy
Starting to serve on 127.0.0.1:8001

无法访问

切换到文件所在目录部署deploy

PS D:\jessetalk\k8s> kubectl create -f .\kubernetes-dashboard.yaml
service "kubernetes-dashboard" created
Error from server (AlreadyExists): error when creating ".\\kubernetes-dashboard.yaml": secrets "kubernetes-dashboard-certs" already exists
Error from server (AlreadyExists): error when creating ".\\kubernetes-dashboard.yaml": serviceaccounts "kubernetes-dashboard" already exists
Error from server (AlreadyExists): error when creating ".\\kubernetes-dashboard.yaml": roles.rbac.authorization.k8s.io "kubernetes-dashboard-minimal" already exists
Error from server (AlreadyExists): error when creating ".\\kubernetes-dashboard.yaml": rolebindings.rbac.authorization.k8s.io "kubernetes-dashboard-minimal" already exists
Error from server (AlreadyExists): error when creating ".\\kubernetes-dashboard.yaml": deployments.apps "kubernetes-dashboard" already exists
PS D:\jessetalk\k8s> kubectl get service -n kube-system
NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)         AGE
kube-dns               ClusterIP   10.96.0.10     <none>        53/UDP,53/TCP   1d
kubernetes-dashboard   NodePort    10.105.60.55   <none>        443:30065/TCP   33s

浏览器访问:https://127.0.0.1:30065/

由于 dashboard 使用 https,所以假的证书无法访问

08-kubectl工具命令介绍

Kubectl 命令详解

kubectl 命令技巧大全

不同 namespace 下的资源(pod, deployment, services)是隔离的

09-yaml部署文件格式介绍

Yaml 部署文件详解

--查看解释
PS C:\WINDOWS\system32> kubectl explain deployment.metadata

学习资料

使用YAML创建一个 Kubernetes Depolyment

#deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8s-demo
  namespace: netcore
  labels:
    name: k8s-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      name: k8s-demo
  template:
    metadata:
      labels:
        name: k8s-demo
    spec:
      containers:
      - name: k8s-demo
        image: 	jessetalk/k8s-demo
        ports:
        - containerPort: 80
        imagePullPolicy: Always

---

kind: Service
apiVersion: v1
metadata:
  name: k8s-demo
  namespace: netcore
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
  selector:
    name: k8s-demo

  • 通过 name 使 Deployment 和 Service 对应
  • imagePullPolicy(策略:总是下载最新的镜像)
#通过 yaml 文件创建服务实例
PS D:\jessetalk\k8s\k8s-demo> kubectl create namespace netcore
namespace "netcore" created
PS D:\jessetalk\k8s\k8s-demo> kubectl get namespace
NAME          STATUS    AGE
default       Active    1d
docker        Active    1d
kube-public   Active    1d
kube-system   Active    1d
netcore       Active    3m
PS D:\jessetalk\k8s\k8s-demo> kubectl create -f deploy.yaml
deployment.apps "k8s-demo" created
service "k8s-demo" created
PS D:\jessetalk\k8s\k8s-demo> kubectl get deploy -n netcore
NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
k8s-demo   2         2         2            2           36s
PS D:\jessetalk\k8s\k8s-demo> kubectl get svc -n netcore
NAME       TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
k8s-demo   NodePort   10.104.253.169   <none>        80:30022/TCP   4m

学习资料

Kubernetes中文社区 | 中文文档

10-部署netcore api到K8S

PS D:\jessetalk\k8s> dotnet new webapi --name k8s-demo

PS D:\jessetalk\k8s> dotnet dev-certs https --trust

PS D:\jessetalk\k8s> dotnet new webapi --name k8s-demo --force

PS D:\jessetalk\k8s> cd k8s-demo

#用 vscode 打开文件
PS D:\jessetalk\k8s\k8s-demo> code .

修改 ValuesController

        // GET api/values/5
        [HttpGet("{id}")]
        public ActionResult<string> Get(int id)
        {
            return id.ToString();
        }

在 VSCode 中 View =》Terminal 输入 dotnet run 本地跑起来

PS D:\jessetalk\k8s\k8s-demo> dotnet run

浏览器地址栏输入:https://localhost:5001/api/values/1 看到结果为1

新建一个 Dockerfile

FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY . .

RUN dotnet restore
RUN dotnet build -c Release -o /app

FROM build AS publish
RUN dotnet publish -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "k8s-demo.dll"]

在 VSCode 终端 build

PS D:\jessetalk\k8s\k8s-demo> docker build -t jessetalk/k8s-demo .

build 成功

Successfully built e143b4e67d1e
Successfully tagged jessetalk/k8s-demo:latest

查看一下镜像,有一个 jessetalk/k8s-demo

PS D:\jessetalk\k8s\k8s-demo> docker images
REPOSITORY                                                       TAG                      IMAGE ID
  CREATED             SIZE
<none>                                                           <none>                   ff94f468e577
  2 minutes ago       1.73GB
jessetalk/k8s-demo                                               latest                   e143b4e67d1e
  24 hours ago        253MB

run ,端口8085映射到80

PS D:\jessetalk\k8s\k8s-demo> docker run -d -p 8085:80 --name k8s-demo jessetalk/k8s-demoa441b03ac073fab5139b3a679b35a6e6260fc595916978137acb6a555ed462b5

查看结果

PS D:\jessetalk\k8s\k8s-demo> docker ps
CONTAINER ID        IMAGE                COMMAND                 CREATED             STATUS              PORTS                  NAMESa441b03ac073        jessetalk/k8s-demo   "dotnet k8s-demo.dll"   2 minutes ago       Up 2 minutes        0.0.0.0:8085->80/tcp   k8s-demof8af1ff029a4        jessetalk/k8s-demo   "dotnet k8s-demo.dll"   2 hours ago         Up 2 hours                                 k8s_k8s-demo_k8s-demo-7d9787fcb9-lnnrp_netcore_0e765fb2-f70c-11e8-8043-00155d0b9215_4c9fffde727a3        jessetalk/k8s-demo   "dotnet k8s-demo.dll"   2 hours ago         Up 2 hours                                 k8s_k8s-demo_k8s-demo-7d9787fcb9-jz2hs_default_73dadea3-f70b-11e8-8043-00155d0b9215_4518f280971f9        jessetalk/k8s-demo   "dotnet k8s-demo.dll"   2 hours ago         Up 2 hours                                 k8s_k8s-demo_k8s-demo-7d9787fcb9-m8slt_default_73e5e434-f70b-11e8-8043-00155d0b9215_4c28b5b43b967        jessetalk/k8s-demo   "dotnet k8s-demo.dll"   2 hours ago         Up 2 hours                                 k8s_k8s-demo_k8s-demo-7d9787fcb9-2j8hx_netcore_0e6fbfca-f70c-11e8-8043-00155d0b9215_4

浏览器访问:http://localhost:8085/api/values

得到返回值:["value1","value2"]

登陆 docker

PS D:\jessetalk\k8s\k8s-demo> docker login --username mingsonzheng
Password:
Login Succeeded

推送镜像(推送前先修改为自己的用户名)

PS D:\jessetalk\k8s\k8s-demo> docker tag jessetalk/k8s-demo mingsonzheng/k8s-demo
PS D:\jessetalk\k8s\k8s-demo> docker push mingsonzheng/k8s-demo
The push refers to repository [docker.io/mingsonzheng/k8s-demo]
3629f42d7187: Pushed
0bb37faafa32: Pushed
b29986f25fdb: Pushed
b116468880ac: Pushed
57bda236ae67: Pushed
ef68f6734aa4: Pushed
latest: digest: sha256:b3dab95b049d2308e2cd94af35dbfeb9c955011a63c1f1caf49faab6ae9d36ff size: 1579

推送完成后可以看到自动创建的仓库 k8s-demo

快速部署 k8s-demo

PS D:\jessetalk\k8s\k8s-demo> kubectl create -f deploy.yaml
service "k8s-demo" created
PS D:\jessetalk\k8s\k8s-demo> kubectl get svc -n netcore
NAME       TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
k8s-demo   NodePort   10.101.30.110   <none>        80:30585/TCP   1m

根据端口号访问本地 k8s 服务:
http://127.0.0.1:30585/api/values
http://127.0.0.1:30585/api/values/1
http://127.0.0.1:30585/api/values/2

通过 dashboard 查看

PS D:\jessetalk\k8s\k8s-demo> kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy
/recommended/kubernetes-dashboard.yaml
secret "kubernetes-dashboard-certs" created
serviceaccount "kubernetes-dashboard" created
role.rbac.authorization.k8s.io "kubernetes-dashboard-minimal" created
rolebinding.rbac.authorization.k8s.io "kubernetes-dashboard-minimal" created
deployment.apps "kubernetes-dashboard" created
service "kubernetes-dashboard" created

启动代理

PS D:\jessetalk\k8s\k8s-demo> kubectl proxy
Starting to serve on 127.0.0.1:8001

浏览器访问:
http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/overview?namespace=default

切换命名空间 netcore,可以看到部署的 k8s-demo

点击容器组,选择一个容器组,点击日志按钮查看日志

点击运行命令进入 docker 的命令行

11-k8s高可用集群介绍

  • 一个集群分为多个 Node (worker节点),左侧为 master 节点
  • 每个节点上安装一个 kubelet ,与 docker 交互,负责每个 Pod 的创建、删除等
  • 外部 service 访问通过 Proxy
  • k8s 所有资源,数据存储在分布式数据库 etcd
  • Scheduler 负责资源调度,根据 Node 负载情况选择 Node 分配任务

k8s 核心组件

  • etcd 保存了整个集群的状态;
  • api server 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
  • controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler 负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
  • kubelet 负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
  • container runtime 负责镜像管理以及Pod和容器的真正运行(CRI);
  • kube-proxy 负责为Service提供cluster内部的服务发现和负载均衡;

k8s 调度过程

  • API Server 异步请求
  • ReplicaSets 副本管理
  • 所有数据保存在 etcd
  • 如果 MasterNode 出现问题,整个集群会挂掉

k8s 高可用集群

  • 一般需要3台 MasterNode,Node 最多25台(与 IP 地址限制有关)
  • etcd 数据库会进行数据同步,通过选举算法选举 leader

12-进阶介绍

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。

posted @ 2019-07-31 00:56  郑子铭  阅读(2254)  评论(2编辑  收藏  举报