精华内容
下载资源
问答
  • 全志F1C200S F1C100S 介绍

    万次阅读 多人点赞 2019-07-15 10:02:54
    那就是全志F1C100S F1C200S,其中F1C100S内置32MB DDR1内存,F1C200S内置64MB DDR1内存。 而他们能从淘宝轻松的买到,如果找靠谱的店家或者找代理商的话,F1C100S 是10块钱一片,F1C200S是13块钱一片。 从淘宝买...

    很久以前发现了一颗性价比极高而且比较好玩的SOC,加群请仔细阅读本博客(见DKTool界面,请备注“来自博客”)

    那就是全志F1C100S F1C200S,其中F1C100S内置32MB DDR1内存,F1C200S内置64MB DDR1内存。

    这个片子能从淘宝轻松的买到,如果找靠谱的店家或者找代理商的话,F1C100S 是10块钱一片,F1C200S是13块钱一片。

    从淘宝买一定要注意分辨是拆机还是库存还是正规代理货源,千万别图便宜,拆机良率可能20%;

     根据用量,找代理商价格100s是9元多,200s是13块左右。我有靠谱的代理联系方式,并可提供BSP。

    这么10来块钱,32MB 和 64MB 的外扩内存都买不到啊,用来驱动RGB屏幕啥的,STM32赶紧靠边站。

    其实F1C100S F1C200S F1C500S F1C600 R6都是一个芯片,他们都是QFN88封装。

    资源方面,

    ARM926ejs内核,主频默认408MHz,据了解做产品出货的一般在600M左右,也有720M出货的。

    有人说可以跑到900MHz,但我没有成功,uboot还没起来就挂了。

    带有100M的SPI接口,2个SDIO接口,1个USB OTG接口,还有CSI摄像头接口,LCD RGB显示屏接口,音频接口。

    I2C I2S UART PWM等等。

    因为引脚比较少,所以复用严重,但也是有考虑的,如果IO不够用,就使用I2C扩展IO。

    我们玩的以F1C100S和F1C200S为主。

    目前能从网上找到的只有F1C200S和F1C600的寄存器手册。其实他们里面的内容都是一模一样的。

    目前能找到F1C200s和F1C600的完整数据手册和寄存器手册,当然完整是相对的,基础外设的寄存器都是开放的,高级解码部分是不开放的。

    关于F1C100S/F1C200S的资料,可以从挖坑网获得,whycan.cn(资料非常零散,找出自己需要的不易)

    里面真是花式玩F1C100S,下面按照系统区分来列举一下:

    1.流出的全志官方C600的BSP ,linux-3.10。支持硬解码编码,但不支持TVIN。可以从github搜到源码,因为C600面向的是智能音箱,所以bsp部分并没有默认支持显示屏,需要自己趟坑修改。其他问题不知。

    2.全志官方的RTOS,名叫melis 2.0。这是全志自己的小系统,支持所有外设,硬件解码编码,TVIN,TVOUT各种外设,学习难度也是很大的,开发环境也是很难,如果能玩转,出些产品还是可以的。不过一般没人去研究他哈。(坑网可以获得)

    3.全志官方的linux,名叫tina。有针对F1C200S的tina版本,3.0或者3.5,内核版本是linux3.10,这个软件支持部分比较丰富,还有比较完善的指导文档。不过这个资料是需要和代理商签NDA的,也就是保密协议,个人或小公司应该是不会被理会的吧。

    4.社区支持的有linux-4.15,linux5.2,linux-5.6不支持硬解解码编码。其中荔枝派用的就是这个,有很多东西也是他们维护的。另外前一阵火的运行linux的名片用的就是这个片子。

    5.XBOOT,九鼎xboot大佬支持的XBOOT,xboot是可以理解为裸机程序也可以理解为一个小系统,可以用来引导linux,也可以用来直接lua开发(很多人玩裸机或rtt从这里提炼驱动),直接用xboot开发也是比较方便的,在xboot群里有人做公司产品的。

    6.RT-thread,这个最开始是RTT支持荔枝派做的,后来RTT有了融资,考虑盈利,把这一部分闭源了做了柿饼pie(串口屏),在网上还能找到之前的资料。原来RTT官方支持的现在不能找到了,不过想玩RTT的饼子们,可以从github找第三方移植的RTT,现在支持了lcd和音频,资料还是不错的。有一个领头人@staunchheart ,他想玩RTT,大家可以找他一起完善 ,他已经可以用RTT的IDE studio进行开发了呢)

    7.UCOS,这是xboot群的大佬,自己移植的ucos,把TVOUT都支持了,移植了NES模拟器,并做了掌机开发板,现在淘宝有售,名字叫小淘气科技,价格也很贵哟,人家可是付出了多少个夜晚研究出来的,有需求的希望支持一下,让做技术的人生活的更开心。

    8.裸机keil开发,这是坑网达克罗德大神自己写的,在坑网上有资料,还可以用jlink调试开发。

    9.VFS,这是simon大佬公司维护的项目,使用IAR,在单片机上跑裸机,并可以运行linux子系统。 

    10.Aodzip大佬做了uboot kernel rootfs的buildroot的支持,并且uboot支持dfu下载程序,支持spi nor启动,spi nand启动,sdio0 4bit 的TF卡,SD NAND,emmc启动;sdio1 1bit 的tf卡或emmc或sd nand的启动。并且支持dfu烧写。好像还支持硬件解码编码,有大佬可以试试。

    玩F1C200S的人大部分是想用来带屏的,所以GUI是大家关心的。 列举一些大家使用的GUI。

    1、周立功的AWTK(首推,打算PDA就用这个了)

    2、开源的littlevgl GUI

    3、Qt

    4、minigui

    5、RTX

    总之,这款片子被大家玩起来了。我也做了个核心板。

    粗略算过,不算flash,核心的BOM成本在15块钱。如果全部自己手焊的话,一块板子不到20。

    这是我画的板子,做了几十个挂淘宝已经卖完了。欢迎大家一起来玩,一起交流。

    现在下图中的板子已经淘汰了,我又设计了新板子呢,而且在做手持机。现在没有可卖的了。如果有想要核心板PCB的话,我可以出售立创EDA工程文件,可以在本文中找到联系群号。我自己都没有可以用的了。

    上图中最底部的两个板子就是最新的核心板,增加了LCD接口,也能接通用40PIN的显示屏了。但我没有 继续做下去,毕竟核心板并不好玩,做来卖也是赚不了几十块钱,而且很麻烦。有一款我在立创库里开源过,后来 无人问津就关闭了呢。

    所以玩就玩的好, 想必各位买板子回去也是想接各种东西进行测试的,所以为什么不做一个集成的板子呢!

    于是PDA开始设计。

    PCB板也已经做好了。

    另外3D图也设计了一下。

    因为视频不好上传,就不上传了,发个截图吧。

    同时呢, 为了方便烧写 固件什么的方便一些,我做个了windows下的图形烧录工具(其实就是封装了一下sunxi-fel)

    1、支持监测插入电脑的芯片型号,判断是F1C100S还是F1C200S,

    2、支持监测spi flash的容量

    3、支持烧录文件到spi flash

    4、支持读取spi flash数据以文件的方式存储

    5、支持烧写文件到DDR

    6、支持读取DDR中数据以文件方式存储

    7、支持读写指定内存地址的32bit数据(可以读写ddr,也可以用来设置寄存器啥的)

    8、我觉得最好的功能还就集成了USB驱动部分,DKTool驱动就是本工具使用的驱动,

    另一个则是烧录全志官方BSP固件用的工具。

    (全志BSP生成的固件内包含了很多东西,比较复杂,搞不懂)


     


    202012月最新DKTool,增加了whycan.cn晕哥的大招,将flash设备模拟为TF卡,内嵌了多款第三方软件


    烧写工具还有很多BUG需要完善,所以不在这发布了。可以到群里去找,最新版本0229,不再更新。以后PDA出来再做配套软件,会加上可以烧写emmc等功能。

    4层板的PDA正在进行中,还制作了钢网,OK了后续再更新。

    PDA的硬件第一版有些不合理,又做了第二版,就是 下面的工程版PDA。

    工程PDA算是OK了,知道了一些BUG,下一版不出问题就是正式版了,

    另外,RGB屏已经驱动成功,音频带喇叭也已经驱动成功,N76E003的 烧录我要改版到可以使用一个Type-C口烧录。

    N76E003模拟N多个额PCF8574。

    不出现什么意外,今年看看能不能做出来。

    2020今年家有喜事,暂时放下了一段时间,慢慢来吧。

    下面绿色的框子不太好看,正式版用的是黑色亚克力。

    2020年10月:

    3寸屏太小了,板子上塞不了多少东西,于是我又换了一个屏幕3.5寸的(大显家的)。

    在此说一下PDA的配置

    CPU:F1C100S/F1C200S

    RAM:内置32MB/64MB

    Flash:TF卡槽焊盘+SD Nand焊盘+EMMC焊盘(看情况进行焊接)

    音频:麦克风+iphone6以上高音质喇叭

    接口:Type-C USB2.0 slave;充电、单片机/SOC下载程序、串口调试单片机/SOC、调试蓝牙模块

               USB2.0 母口  可以插U盘

    按键:美上美优质滚轮编码器(手感贼棒!!!)

    屏幕:3.5寸电容触摸 480*800分辨率 IPS屏 非全贴合

    摄像头:OV5640 500万像素

    WiFi:ESP8266EX  工作在sdio网卡模式,实测速度1MB/S

    蓝牙:杰里方案,支持连接手机,通过该蓝牙,可以手机放歌,当蓝牙音箱用;可以借助蓝牙功能,PDA实现打电话功能。可以BLE数据传输,通过微信小程序配置WIFI网络。

    电源管理:暂时保密,同时锂电池充电管理

    电池:诺基亚BL-5C  1000mAh

    包边:不锈钢装饰条

    正反面:亚克力广告贴(最终效果逼格高!)

    2021年7月:

    换屏了,3.8寸的带弧度的屏,这样做出来才像PDA

    画一半,先发一下。

    展开全文
  • 里面有做好的vivi zImage 和文件系统root.cramfs和应用程序yaffs.tar.bz2,可以直接通过串口下载到开发板,但是只在S3C2410上面试过,
  • 一文带你深入了解K8S实战部署SpringBoot项目

    1.前言

    云原生可以说是当下互联网行业最火爆的概念和技术,云原生从字面意思上来看可以分成云和原生两个部分。
    是和本地相对的,传统的应用必须跑在本地服务器上,现在流行的应用都跑在云端,云包含了IaaS,、PaaS和SaaS。
    原生就是土生土长的意思,我们在开始设计应用的时候就考虑到应用将来是运行云环境里面的,要充分利用云资源的优点,比如️云服务的弹性和分布式优势。
    聊到云原生,避不开的就是容器技术,而docker作为最流行的容器技术,已经经过很多年的线上实战。今天我们不深入聊云原生,docker这些技术概念,今天我们聊一聊时下最火的容器编排技术:K8S-实战部署SpringBoot项目。

    2.简介

    2.1.为什么写这篇文章

    前言中提到云原生dockerK8S,我是18年第一次docker,也是在18年接触K8S,相对这门技术来说,我接触的时候已经有些晚了,因为在之后的面试中,已经感受到这些技术在大厂已经用的很成熟了,之前都在小公司,并不了解这些技术是什么,干什么用,加上国内这方面的资料又比较少,学起来是相当吃力。而到大厂之后,发现这些技术无处不在,并且基础设施建设已经很完备,一键部署云端的骚操作,让开发只需要关心业务而无需关心安装部署等繁琐的工作。祸兮福之所倚;福兮祸之所伏,大厂的技术设施完备的同时,另一方面也消弱了你去了解基础设施背后的技术原理能力。正是认识到这一点,今天才写这篇文章,为迷途中的孩子找到回家的路。废话不多,撸起袖子,干就完了!

    这里没有任何马后炮套话,只有粗暴的干货。写大家看得懂、用得着、赚得到的文章是唯一宗旨!

    2.2.需求描述

    我有一个简单的Springboot项目,想部署在K8S集群中,能够实现扩缩容,负载均衡,同时我有一个互联网域名,我想把这个域名绑定在这个服务上,能够在有网络的地方访问。

    2.3.需求分析

    这个需求我想在很多刚开始接触docker,k8s等技术的老铁身上都会遇到过,真正实现起来,并不是那么容易,听我一一道来:

    1. image—Springboot项目一般是以jar包的形式跑在像centos等服务器上,运行nohup java -jar xxx.jar &命令就能启动起来。但是在k8s中,运行起来的的并不是jar,而是image,因此我们需要把jar打包成image;
    2. 自动扩缩—最基础的image有了,接下来就要考虑的是自动扩缩:顾名思义,比如说就是在服务访问量大的时候,我可以添加实例,来减少每个服务实例的压力,在访问量小的时候,我可以删除一部分实例,来实现资源的高效利用。
    3. 负载均衡—当我们的实例越来越多,我并不希望把所有的请求都落在一个实例上,如若不然,我们自动扩缩也就没了意义,传统方法我们可以用Nginx等实现负载均衡,待会来看看K8S能做些什么
    4. 域名绑定—这个就没什么好说的了。

    3. 部署实战

    3.1 环境准备

    工欲善其事,必先利其器:

    1. Springboot jar包
    2. K8S集群环境

    K8S集群环境部署我就不在这里展开讲了,我们准备一个最简单的Springboot项目,里面只有一个接口,访问localhost:8088,返回服务器的hostname,当整个部署工作完成之后,我们通过域名访问这个接口,返回的应该是不同的containerhostname,那我们的任务就完成了。

    	@GetMapping("/")
        public String sayHello() throws UnknownHostException {
            String hostname = "Unknown";
            InetAddress address = InetAddress.getLocalHost();
            hostname = address.getHostName();
            return hostname;
        }
    

    3.2 image准备

    我们都知道,所有image的生成都离不开Dockerfile技术,我们有了一个jar包,要利用Dockerfile技术生成一个image。废话不多,上代码:

    #使用jdk8作为基础镜像
    FROM java:8
    #指定作者
    MAINTAINER ***
    #暴漏容器的8088端口
    #EXPOSE 8088
    #将复制指定的docker-demo-0.0.1-SNAPSHOT.jar为容器中的job.jar,相当于拷贝到容器中取了个别名
    ADD docker-demo-0.0.1-SNAPSHOT.jar /job.jar
    #创建一个新的容器并在新的容器中运行命令
    RUN bash -c 'touch /job.jar'
    #设置时区
    ENV TZ=PRC
    RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
    #相当于在容器中用cmd命令执行jar包  指定外部配置文件
    ENTRYPOINT ["java","-jar","/job.jar"]
    

    Dockerfile文件里面有注释,具体的每一行代码什么意思我就不展开多讲了,这不是今天的重点,接下来,我们把docker-demo-0.0.1-SNAPSHOT.jarDockerfile文件放在同一个目录,上传到K8S的master 节点上,在目录内执行如下命令生成images

    $ docker build .
    

    我们可以看到生成image的过程,通过docker images 查看镜像
    在这里插入图片描述
    生成一个 docker-demo:latest的image镜像。
    注意:我们部署的是集群,要想K8S集群中都能拉到这个镜像,那我们有以下两种方式:

    1. 方法一:我们把这个docker-demo:latest上传到远端仓库,这个仓库可以是我们自己的,或者是像我一样注册一个阿里云的账号,上传到阿里云自己的容器镜像服务仓库,如下图:
      在这里插入图片描述
      具体步骤
      1.1 docker登陆阿里云容器镜像服务,需要输入密码
    $ docker login --username=24k不怕(写自己的用户名) registry.cn-hangzhou.aliyuncs.com
    

    1.2 在阿里云上创建命名空间:例:cuixhao-docker-demo
    在这里插入图片描述
    1.3 镜像打标签

    $ docker tag docker-demo:latest registry.cn-hangzhou.aliyuncs.com/cuixhao-docker-demo/docker-demo:latest
    

    1.4 push到阿里云

    $ docker push registry.cn-hangzhou.aliyuncs.com/cuixhao-docker-demo/docker-demo:latest
    

    1.5 删除掉docker-demo:latest

    $ docker rmi docker-demo:latest
    
    1. 方法二 把刚才创建image的过程,在集群中每一台节点上都执行一遍,保证集群中每一台都有这个镜像。我采用的是二者的结合:先在master上把镜像生成,上传到阿里云,然后在另外的节点上,通过docker pull registry.cn-hangzhou.aliyuncs.com/cuixhao-docker-demo/docker-demo:latest 命令,从阿里云上拉到本地,然后在通过 docer tag registry.cn-hangzhou.aliyuncs.com/cuixhao-docker-demo/docker-demo:latest docker-demo:latest命令打标签,然后删掉拉取到的镜像:docker rmi registry.cn-hangzhou.aliyuncs.com/cuixhao-docker-demo/docker-demo:latest,
      为什么这么做因为我阿里云建的命名空间中的image都是私有,K8S拉取image的时候是需要集群中都配置ca证书的,如果设置为公开则不存在这个问题。所以我用docker-demo:latest这个镜像,直接用本地的,部署的时候不用再去阿里云拉取。

    3.3 部署2个实例

    3.3.1 编写yaml文件

    基础镜像准备好了,那我们就开始部署吧。我们知道,k8s有deployment ,service等概念,这里不详细讲,简单描述一下:deployment,管理pod集群,service,管理pod中的服务。我们在master 节点编辑一个 ingress-docker-docker-deployment.yaml 文件

    $ vi ingress-docker-docker-deployment.yaml
    

    键入以下内容

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ingress-docker-demo-deployment
      labels:
        app: ingress-docker-demo
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: ingress-docker-demo
      template:
        metadata:
          labels:
            app: ingress-docker-demo
        spec:
          containers:
          - name: docker-demo
            image: docker-demo
            imagePullPolicy: Never
            ports:
            - containerPort: 8088
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: ingress-docker-demo-service
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 8088
      selector:
        app: ingress-docker-demo
    

    由yaml文件内容我们可以读出:我们创建了一个 名字我为ingress-docker-demo-deployment的deployment,里面有2个 docker-demo 的pod (replicas: 2),和一个名字为ingress-docker-demo-service的service,管理名字为ingress-docker-demo的pod服务,目标端口8088,即我们的springboot服务所用端口,对外提供80端口。

    3.3.2 启动

    在master执行如下命令启动deployment 和service:

    $ kubectl apply -f ingress-docker-docker-deployment.yaml
    

    查看启动结果:

    $ kubectl get pod -o wide
    

    在这里插入图片描述
    我们可以看到启动结果,两个container分别在 worker01,worker02这两个节点上,可以看到,K8S集群给我们分配了两个IP:192.168.14.11,192.168.221.73。我们思考以下三个问题:
    a. 在集群中,我们通过以上访问这两个服务,能访问通吗,是通过8088端口还是80端口?
    我们不妨尝试一下,在集群中任何一个节点执行如下命令:

    $ curl 192.168.14.11:8088
    $ curl 192.168.221.73:8088
    

    在这里插入图片描述
    我们可以看到,接口返回了各自container的hostname,说明我们的服务是部署启动成功了,访问80端口是不通的,有兴趣的老铁可以试一下,因为80是我们对外的端口,所以用container ip是访问不通的。
    b. 在集群内部访问,我们如何做到负载均衡?
    有老铁可能会考虑一个问题,K8S集群中的pod有可能销毁或者重启,每次重启之后的ip不能保证一致,那以上访问方式肯定是不可采用的。想法很对,我们想访问一个固定的地址,不管pod如何重启,ip如何变化,我只访问这一个ip,这岂不美哉?那我们能不能做到呢?且看如下骚操作:

    $ kubectl get svc
    

    在这里插入图片描述
    通过以上命令,我们找到了ingress-docker-docker-deployment.yaml中定义的名字为 ingress-docker-demo-service的service,它有一个 CLUSTER-IP,PORT为80,那我们根据K8S中的service的作用,做一个大胆的猜测:我们是不是可以固定的通过 10.103.19.71 (省略默认80端口)或者 10.103.19.71:80 来永久访问这两个服务呢?

    $ curl 10.103.19.71
    $ curl 10.103.19.71:80
    

    在这里插入图片描述
    答案是肯定的!,它给我们做了负载均衡!

    c. 在集群外部我们如何访问这两个服务并且负载均衡?
    集群内访问服务,负载均衡都已经做好了。有的老铁会问:集群外服想访问集群内的服务,该如何做呢?别急,还没完!

    3.3.3 引入Ingress

    3.3.3.1 Ingress简介

    我们传统的集群负载均衡做法是在一台机器上安装Nginx,把我们的服务配置在Nginx上,外部直接访问你Nginx,它帮我们做负载,做限流,但是今天我们玩了K8S,就不能在用这种方法了,我们大胆的想一下,我们把所有的东西都在K8S做了,岂不美哉!想法很好,"好事者"已经替我们想到了,并且替我们做到了。
    kubernetes ingress 文档
    我来简单介绍一下:
    在这里插入图片描述
    如图:在K8S中,Ingress 提供 controller接口,由各个负载均衡厂家实现,传统Nginx是配置在nginx.conf 中,在K8S中,我们只需要配置Ingress 资源yaml就可以,听起来是不是方便多了,我们可以像管理deployment,servicepod一样管理Ingress
    在这里插入图片描述

    3.3.3.2 Ingress 安装

    我们使用 Nginx Ingress Controller 来一波骚操作:
    编写 ingress-nginx.yaml

    $ vi  ingress-nginx.yaml
    

    键入以下内容:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: ingress-nginx
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    
    ---
    
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: nginx-configuration
      namespace: ingress-nginx
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    
    ---
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: tcp-services
      namespace: ingress-nginx
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    
    ---
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: udp-services
      namespace: ingress-nginx
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: nginx-ingress-serviceaccount
      namespace: ingress-nginx
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    
    ---
    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRole
    metadata:
      name: nginx-ingress-clusterrole
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    rules:
      - apiGroups:
          - ""
        resources:
          - configmaps
          - endpoints
          - nodes
          - pods
          - secrets
        verbs:
          - list
          - watch
      - apiGroups:
          - ""
        resources:
          - nodes
        verbs:
          - get
      - apiGroups:
          - ""
        resources:
          - services
        verbs:
          - get
          - list
          - watch
      - apiGroups:
          - ""
        resources:
          - events
        verbs:
          - create
          - patch
      - apiGroups:
          - "extensions"
          - "networking.k8s.io"
        resources:
          - ingresses
        verbs:
          - get
          - list
          - watch
      - apiGroups:
          - "extensions"
          - "networking.k8s.io"
        resources:
          - ingresses/status
        verbs:
          - update
    
    ---
    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: Role
    metadata:
      name: nginx-ingress-role
      namespace: ingress-nginx
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    rules:
      - apiGroups:
          - ""
        resources:
          - configmaps
          - pods
          - secrets
          - namespaces
        verbs:
          - get
      - apiGroups:
          - ""
        resources:
          - configmaps
        resourceNames:
          # Defaults to "<election-id>-<ingress-class>"
          # Here: "<ingress-controller-leader>-<nginx>"
          # This has to be adapted if you change either parameter
          # when launching the nginx-ingress-controller.
          - "ingress-controller-leader-nginx"
        verbs:
          - get
          - update
      - apiGroups:
          - ""
        resources:
          - configmaps
        verbs:
          - create
      - apiGroups:
          - ""
        resources:
          - endpoints
        verbs:
          - get
    
    ---
    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: RoleBinding
    metadata:
      name: nginx-ingress-role-nisa-binding
      namespace: ingress-nginx
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: nginx-ingress-role
    subjects:
      - kind: ServiceAccount
        name: nginx-ingress-serviceaccount
        namespace: ingress-nginx
    
    ---
    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRoleBinding
    metadata:
      name: nginx-ingress-clusterrole-nisa-binding
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: nginx-ingress-clusterrole
    subjects:
      - kind: ServiceAccount
        name: nginx-ingress-serviceaccount
        namespace: ingress-nginx
    
    ---
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-ingress-controller
      namespace: ingress-nginx
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/part-of: ingress-nginx
      template:
        metadata:
          labels:
            app.kubernetes.io/name: ingress-nginx
            app.kubernetes.io/part-of: ingress-nginx
          annotations:
            prometheus.io/port: "10254"
            prometheus.io/scrape: "true"
        spec:
          # wait up to five minutes for the drain of connections
          terminationGracePeriodSeconds: 300
          serviceAccountName: nginx-ingress-serviceaccount
          hostNetwork: true
          nodeSelector:
            name: ingress
            kubernetes.io/os: linux
          containers:
            - name: nginx-ingress-controller
              image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1
              args:
                - /nginx-ingress-controller
                - --configmap=$(POD_NAMESPACE)/nginx-configuration
                - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
                - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
                - --publish-service=$(POD_NAMESPACE)/ingress-nginx
                - --annotations-prefix=nginx.ingress.kubernetes.io
              securityContext:
                allowPrivilegeEscalation: true
                capabilities:
                  drop:
                    - ALL
                  add:
                    - NET_BIND_SERVICE
                # www-data -> 33
                runAsUser: 33
              env:
                - name: POD_NAME
                  valueFrom:
                    fieldRef:
                      fieldPath: metadata.name
                - name: POD_NAMESPACE
                  valueFrom:
                    fieldRef:
                      fieldPath: metadata.namespace
              ports:
                - name: http
                  containerPort: 80
                - name: https
                  containerPort: 443
              livenessProbe:
                failureThreshold: 3
                httpGet:
                  path: /healthz
                  port: 10254
                  scheme: HTTP
                initialDelaySeconds: 10
                periodSeconds: 10
                successThreshold: 1
                timeoutSeconds: 10
              readinessProbe:
                failureThreshold: 3
                httpGet:
                  path: /healthz
                  port: 10254
                  scheme: HTTP
                periodSeconds: 10
                successThreshold: 1
                timeoutSeconds: 10
              lifecycle:
                preStop:
                  exec:
                    command:
                      - /wait-shutdown
    
    ---
    

    这个文件并不是我胡编乱造自己写的,是"好事者"帮我们做好了,我只是稍作修改:设置网络模式为hostNetwork:true,我希望我在集群中一台机器上开一个80端口,用这台机器作为负载均衡入口,因此:nodeSelector: name: ingress。这是节点选择器配置参数,设置这个,ingress服务会在节点名字为ingress的机器上部署。
    在这里插入图片描述
    接下来我们在集群中的除master节点之外的一个机器上执行下个命令:给这台hostname为worker01-kubeadm-k8s的机器取个别名ingress

    $ kubectl label node worker01-kubeadm-k8s name=ingress
    

    接下来,我们在master节点执行安装ingress操作

    $ kubectl apply -f ingress-nginx.yaml
    

    安装过程有点儿慢,因为有个镜像比较难拉取:quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1,建议执行 docker pull 先拉取到本地,上传到阿里云,然后在各个节点从阿里云拉取,然后在打tag的骚操作,都是有经验的程序员,你们知道我在说什么!

    3.3.3.3 Ingress 配置启动

    编写Ingress yaml资源:

    $ vi nginx-ingress.yaml
    

    键入以下内容:

    #ingress
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: nginx-ingress
    spec:
      rules:
      - host: test.test.com
        http:
          paths:
          - path: /
            backend:
              serviceName: ingress-docker-demo-service
              servicePort: 80
    

    文件定义了一种Ingress的资源,配置host为:test.test.com,代理K8S中名字为ingress-docker-demo-service的 Service, Service端口为80.看起来是不是和Nginx配置有点儿类似?
    最后一步:启动

    $ kubectl apply -f nginx-ingress.yaml
    

    3.3.3.4 验证

    因为test.test.com是不存在的域名,我们都是有经验的开发人员,很自然的想到去修改本地host : 添加 ip test.test.com,ip为K8S节点中设置的别名为ingress的ip地址
    浏览器访问:
    在这里插入图片描述
    在这里插入图片描述
    完美!

    3.3.3.4 自动扩缩

    使用如下命令,可以然服务实现自动扩缩:

    $ kubectl autoscale ingress-docker-docker-deployment.yaml --min=2 --max=5 --cpu-percent=80
    

    还有很多自动扩缩的规则,老铁们自己探讨!

    4. 总结

    K8S实战还有很多玩法,我今天只是讲了最简单的服务部署,在不同的生产环境中,需求也是不一样的,比如说:一个简单的web应用,有mysql数据库,有redis,有springboot应用,都要在K8S中实践,这又是另一种部署方法,但万变不离其宗核心都是要深入了解K8S网络,只有网络打通了,各个组件才会畅通无阻的运行。有兴趣的老铁可以关注一波,一起Hello World!

    下一篇:K8S实战进阶篇:一文带你深入了解K8S持久化存储解决方案

    展开全文
  • MATLABS-Function s函数简单应用

    千次阅读 2019-06-26 21:09:06
    文章目录什么叫S函数用MATLAB语言编写S函数(1)主函数(2)子函数S函数的应用(1)定义s函数1.主函数2.初始化子函数3.输出子函数完整代码(2)在Simulink模型中使用S函数 B站av52613760/p52 什么叫S函数 s函数是系统函数...


    参照B站av52613760/p52视频,视频中和我所用的MATLABR20141a不同,改动后在我的版本上运行成功

    什么叫S函数

    • s函数是系统函数(System Function)的简称,是指采用一种程序设计语言描述的一个功能模块。
    • 用户可以采用MATLAB语言,也可以采用C、C++或FORTRAN等语言来编写S函数。
    • S函数有自己特定的语法构成规则,可以用来描述并实现连续系统、离散系统以及复合系统。
    • S函数能够接收来自Simulink求解算法的相关信息,并对求解算法发出的命令做出适当的响应,这种交互作用类似于Simulink系统模块与求解算法的相互作用。

    用MATLAB语言编写S函数

    在MATLAB命令行窗囗输入命令,打开模板文件。

    >> edit sfuntmpl.m
    

    模板文件sfuntmpl.m包括:

    • 1个主函数
    • 6个子函数

    (1)主函数

    主函数的引导语句为:
    function [sys,x0,str,ts]=fname(t,x,u,flag)

    • fmame是S函数的函数名.
    • 输入形参t、x、u、flag分别为仿真时间、状态向量、输入向量和子函数调用标志.
    • 输出形参sys代表一种返回参数;×0是初始状态值;对于M文件S函数,str将被置成一个空阵;ts是一个两列矩阵(一列是各状态变量的采样周期,一列是相应的采样时间的偏移量).TS = [0 0] 连续采样 ;TS =[-1 0]继承被连接模块的采样时间

    (2)子函数

    S函数共有6个子函数,这些子函数的前辍为mdl,由flag的值来控制在仿真的各阶段调用S函数的哪一个子函数.

    • flag取0:调用初始化子函数mdllnitializeSizes.
    • flag取1:调用子函数mdlDerivatives实现连续状态的更新.
    • flag取2:调用子函数mdlUpdate实现离散状态的更新.
    • Flag取3:调用输出子函数mdlOutputs.
    • flag取4,9的情况较少使用

    S函数的应用

    采用S函数实现y=kx+b.

    (1)定义s函数

    1.主函数

    function [sys,x0,str,ts]=timekb(t,x,u,flag,k,b)
    switch flag
        case 0
            [sys,x0,str,ts]=mdlInitializeSizes;%初始化
        case 3
            sys=mdlOutputs(t.x.u,k.b);%计算输出量
    %该段其余代码与模板一致
    
    end
    

    2.初始化子函数

    function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes
    sizes=simsizes;
    sizes.NumContStates=0;%无连续状态
    sizes.NumDiscStates=0;%无离散状态
    sizes.NumOutputs=1;%有一个输出量
    sizes.NumInputs=1;%有一个输入信号
    sizes.DirFeedthrough=1;%输出量中含有输入量
    sizes.NumSampleTimes=1;%单个采样周期
    sys=simsizes(sizes);
    %给其他返回参数赋值
    X0=[];%设置初始状态为零状态
    str=[];%将str变量设置为空字符串
    ts=[-1,0];%假定继承输入信号的采样周期
    

    3.输出子函数

    function sys=mdlOutputs(t,x,u,k,b)%t仿真时间,x状态向量,u输入向量,k,b自定义参数
    sys=k*u+b;
    

    完整代码

    以下代码为在模板按照上述说明做改动,所用软件版本为matlabR2014a且成功运行

    function [sys,x0,str,ts,simStateCompliance] = timeFunctionkb(t,x,u,flag,k,b)%%较模板加入k.b
    %SFUNTMPL General MATLAB S-Function Template
    %   With MATLAB S-functions, you can define you own ordinary differential
    %   equations (ODEs), discrete system equations, and/or just about
    %   any type of algorithm to be used within a Simulink block diagram.
    %
    %   The general form of an MATLAB S-function syntax is:
    %       [SYS,X0,STR,TS,SIMSTATECOMPLIANCE] = SFUNC(T,X,U,FLAG,P1,...,Pn)
    %
    %   What is returned by SFUNC at a given point in time, T, depends on the
    %   value of the FLAG, the current state vector, X, and the current
    %   input vector, U.
    %
    %   FLAG   RESULT             DESCRIPTION
    %   -----  ------             --------------------------------------------
    %   0      [SIZES,X0,STR,TS]  Initialization, return system sizes in SYS,
    %                             initial state in X0, state ordering strings
    %                             in STR, and sample times in TS.
    %   1      DX                 Return continuous state derivatives in SYS.
    %   2      DS                 Update discrete states SYS = X(n+1)
    %   3      Y                  Return outputs in SYS.
    %   4      TNEXT              Return next time hit for variable step sample
    %                             time in SYS.
    %   5                         Reserved for future (root finding).
    %   9      []                 Termination, perform any cleanup SYS=[].
    %
    %
    %   The state vectors, X and X0 consists of continuous states followed
    %   by discrete states.
    %
    %   Optional parameters, P1,...,Pn can be provided to the S-function and
    %   used during any FLAG operation.
    %
    %   When SFUNC is called with FLAG = 0, the following information
    %   should be returned:
    %
    %      SYS(1) = Number of continuous states.
    %      SYS(2) = Number of discrete states.
    %      SYS(3) = Number of outputs.
    %      SYS(4) = Number of inputs.
    %               Any of the first four elements in SYS can be specified
    %               as -1 indicating that they are dynamically sized. The
    %               actual length for all other flags will be equal to the
    %               length of the input, U.
    %      SYS(5) = Reserved for root finding. Must be zero.
    %      SYS(6) = Direct feedthrough flag (1=yes, 0=no). The s-function
    %               has direct feedthrough if U is used during the FLAG=3
    %               call. Setting this to 0 is akin to making a promise that
    %               U will not be used during FLAG=3. If you break the promise
    %               then unpredictable results will occur.
    %      SYS(7) = Number of sample times. This is the number of rows in TS.
    %
    %
    %      X0     = Initial state conditions or [] if no states.
    %
    %      STR    = State ordering strings which is generally specified as [].
    %
    %      TS     = An m-by-2 matrix containing the sample time
    %               (period, offset) information. Where m = number of sample
    %               times. The ordering of the sample times must be:
    %
    %               TS = [0      0,      : Continuous sample time.
    %                     0      1,      : Continuous, but fixed in minor step
    %                                      sample time.
    %                     PERIOD OFFSET, : Discrete sample time where
    %                                      PERIOD > 0 & OFFSET < PERIOD.
    %                     -2     0];     : Variable step discrete sample time
    %                                      where FLAG=4 is used to get time of
    %                                      next hit.
    %
    %               There can be more than one sample time providing
    %               they are ordered such that they are monotonically
    %               increasing. Only the needed sample times should be
    %               specified in TS. When specifying more than one
    %               sample time, you must check for sample hits explicitly by
    %               seeing if
    %                  abs(round((T-OFFSET)/PERIOD) - (T-OFFSET)/PERIOD)
    %               is within a specified tolerance, generally 1e-8. This
    %               tolerance is dependent upon your model's sampling times
    %               and simulation time.
    %
    %               You can also specify that the sample time of the S-function
    %               is inherited from the driving block. For functions which
    %               change during minor steps, this is done by
    %               specifying SYS(7) = 1 and TS = [-1 0]. For functions which
    %               are held during minor steps, this is done by specifying
    %               SYS(7) = 1 and TS = [-1 1].
    %
    %      SIMSTATECOMPLIANCE = Specifices how to handle this block when saving and
    %                           restoring the complete simulation state of the
    %                           model. The allowed values are: 'DefaultSimState',
    %                           'HasNoSimState' or 'DisallowSimState'. If this value
    %                           is not speficified, then the block's compliance with
    %                           simState feature is set to 'UknownSimState'.
     
     
    %   Copyright 1990-2010 The MathWorks, Inc.
     
    %
    % The following outlines the general structure of an S-function.
    %
    switch flag,
     
      %%%%%%%%%%%%%%%%%%
      % Initialization %
      %%%%%%%%%%%%%%%%%%
      case 0,
        [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;
     
      %%%%%%%%%%%%%%%
      % Derivatives %
      %%%%%%%%%%%%%%%
      case 1,
        sys=mdlDerivatives(t,x,u);
     
      %%%%%%%%%%
      % Update %
      %%%%%%%%%%
      case 2,
        sys=mdlUpdate(t,x,u);
     
      %%%%%%%%%%%
      % Outputs %
      %%%%%%%%%%%
      case 3,
        sys=mdlOutputs(t,x,u,k,b);%%%%较模板加入k.b
     
      %%%%%%%%%%%%%%%%%%%%%%%
      % GetTimeOfNextVarHit %
      %%%%%%%%%%%%%%%%%%%%%%%
      case 4,
        sys=mdlGetTimeOfNextVarHit(t,x,u);
     
      %%%%%%%%%%%%%
      % Terminate %
      %%%%%%%%%%%%%
      case 9,
        sys=mdlTerminate(t,x,u);
     
      %%%%%%%%%%%%%%%%%%%%
      % Unexpected flags %
      %%%%%%%%%%%%%%%%%%%%
      otherwise%出错处理
        DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));
     
    end
     
    % end sfuntmpl
     
    %
    %=============================================================================
    % mdlInitializeSizes
    % Return the sizes, initial conditions, and sample times for the S-function.
    %=============================================================================
    %
    function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes
     
    %
    % call simsizes for a sizes structure, fill it in and convert it to a
    % sizes array.
    %
    % Note that in this example, the values are hard coded.  This is not a
    % recommended practice as the characteristics of the block are typically
    % defined by the S-function parameters.
    %
    sizes = simsizes;
     
    sizes.NumContStates  = 0;
    sizes.NumDiscStates  = 0;
    sizes.NumOutputs     = 1;
    sizes.NumInputs      = 1;
    sizes.DirFeedthrough = 1;
    sizes.NumSampleTimes = 1;   % at least one sample time is needed
     
    sys = simsizes(sizes);
     
    %
    % initialize the initial conditions
    %
    x0  = [];
     
    %
    % str is always an empty matrix
    %
    str = [];
     
    %
    % initialize the array of sample times
    %
    ts  = [-1 0];
     
    % Specify the block simStateCompliance. The allowed values are:
    %    'UnknownSimState', < The default setting; warn and assume DefaultSimState
    %    'DefaultSimState', < Same sim state as a built-in block
    %    'HasNoSimState',   < No sim state
    %    'DisallowSimState' < Error out when saving or restoring the model sim state
    simStateCompliance = 'UnknownSimState';
     
    % end mdlInitializeSizes
     
    %
    %=============================================================================
    % mdlDerivatives
    % Return the derivatives for the continuous states.
    %=============================================================================
    %
    function sys=mdlDerivatives(t,x,u)
     
    sys = [];
     
    % end mdlDerivatives
     
    %
    %=============================================================================
    % mdlUpdate
    % Handle discrete state updates, sample time hits, and major time step
    % requirements.
    %=============================================================================
    %
    function sys=mdlUpdate(t,x,u)
     
    sys = [];
     
    % end mdlUpdate
     
    %
    %=============================================================================
    % mdlOutputs
    % Return the block outputs.
    %=============================================================================
    %
     
    function sys=mdlOutputs(t,x,u,k,b)%%t仿真时间,x状态向量,u输入向量,k,b自定义参数
    sys=k*u+b;
    % end mdlOutputs
     
    %
    %=============================================================================
    % mdlGetTimeOfNextVarHit
    % Return the time of the next hit for this block.  Note that the result is
    % absolute time.  Note that this function is only used when you specify a
    % variable discrete-time sample time [-2 0] in the sample time array in
    % mdlInitializeSizes.
    %=============================================================================
    %
    function sys=mdlGetTimeOfNextVarHit(t,x,u)
     
    sampleTime = 1;    %  Example, set the next hit to be one second later.
    sys = t + sampleTime;
     
    % end mdlGetTimeOfNextVarHit
     
    %
    %=============================================================================
    % mdlTerminate
    % Perform any end of simulation tasks.
    %=============================================================================
    %
    function sys=mdlTerminate(t,x,u)
     
    sys = [];
     
    % end mdlTerminate
    
    

    (2)在Simulink模型中使用S函数

    做好了s函数后,simulink–user-defined function下拖一个S-Function到你的模型,就可以用了;在simulink——-user-defined function还有个s-Function Builder,他可以生成用c语言写的s函数;
    在matlab的workspace下打sfundemos,可以看到很多演示s函数的程序
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    设置完之后,点击运行,再点击查看波形可得如下结果
    运行之后得出此波形

    展开全文
  • 首先分析了C/S、B/S两种管理模式的各自特点,进而提出了C/S、B/S两种模式交叉并用的学生学籍管理信息系统的设计思想和结构形式,并具体介绍了该系统在高校学生学籍管理当中的应用,以及如何做好系统的维护工作。
  • k8s 基本使用

    万次阅读 2018-02-07 17:06:56
    k8s 原理   kubernetes API server 作为集群的核心,负责集群各功能之间的通信, 集群内的各个功能模块通过API Server将信息存入etcd,当需要获取和操作这些数据的时候 通过API Server 提供的 REST ...

    k8s 原理

     

    kubernetes API server 作为集群的核心,负责集群各功能之间的通信, 集群内的各个功能模块通过API Server将信息存入etcd,当需要获取和操作这些数据的时候

    通过API Server 提供的 REST 接口(get put post watch) 来实现。

     

    场景一: node节点的 kubelet --------> apiserver

    node上的 kubelet 进程每隔一个时间周期,就会调用一次API Server接口报告自身状态,API Server接受这些信息后,将节点状态更新到etcd中

    kubelet也通过API Server的 WATCH接口监听pod信息,如果监控到新的pod副本被调度绑定到本节点,则执行pod对应的容器的创建和启动,如果

    如果监听到pod对象被删除,则删除本节点对应的pod容器。

     

    场景二: master kube-controller-manager  --------> apiserver

    kube-controller-manager 中的node controller 模块通过 API Server提供的Watch接口,实时监控node的状态信息

    controller-manager 作为集群内部的管理控制中心,负责集群内的node,pod副本, 命名空间namespace, 服务账号,资源定额等的管理,当某个node 宕机,

    controller manager 就会及时防线故障并自动修复。

     

     

     

     

    k8s网络

    使用weave网络

     

     

     

     

     

     

     

     

     

     

     

     

    复制代码
    etcd 中注册的对象内容。

    [root@docker1 ~]# etcdctl ls /registry /registry/controllers /registry/daemonsets /registry/namespaces /registry/ranges /registry/replicasets /registry/serviceaccounts /registry/ingress /registry/clusterrolebindings /registry/secrets /registry/services /registry/certificatesigningrequests /registry/configmaps /registry/clusterroles /registry/deployments /registry/events /registry/minions /registry/pods
    复制代码

     

     

    复制代码
    API server: 提供了HTTP Rest接口,可以对所有资源进行增 删 改 查,是整个集群的入口
    controller Mananter: 所有资源对象的自动化控制中心
    
    scheduler: 负责资源调度。
    
    kubelet,负责pod的创建 启停,与master 节点密切协作,实现集群管理的功能
    kube-proxy: 实现service的通信与负载均衡机制
    复制代码

     

     

    DaemonSet

    DaemonSet能够让所有(或者一些特定)的Node节点运行同一个pod。当节点加入到kubernetes集群中,pod会被(DaemonSet)调度到该节点上运行,当节点从kubernetes集群中被移除,被(DaemonSet)调度的pod会被移除,如果删除DaemonSet,所有跟这个DaemonSet相关的pods都会被删除。

    在使用kubernetes来运行应用时,很多时候我们需要在一个区域(zone)或者所有Node上运行同一个守护进程(pod),例如如下场景:

    • 每个Node上运行一个分布式存储的守护进程,例如glusterd,ceph
    • 运行日志采集器在每个Node上,例如fluentd,logstash
    • 运行监控的采集端在每个Node,例如prometheus node exporter,collectd等

    在简单的情况下,一个DaemonSet可以覆盖所有的Node,来实现Only-One-Pod-Per-Node这种情形;在有的情况下,我们对不同的计算几点进行着色,或者把kubernetes的集群节点分为多个zone,DaemonSet也可以在每个zone上实现Only-One-Pod-Per-Node。

     

    什么是Deployment

    Kubernetes Deployment提供了官方的用于更新Pod和Replica Set(下一代的Replication Controller)的方法,您可以在Deployment对象中只描述您所期望的理想状态(预期的运行状态),Deployment控制器为您将现在的实际状态转换成您期望的状态,例如,您想将所有的webapp:v1.0.9升级成webapp:v1.1.0,您只需创建一个Deployment,Kubernetes会按照Deployment自动进行升级。现在,您可以通过Deployment来创建新的资源(pod,rs,rc),替换已经存在的资源等。

    Deployment集成了上线部署、滚动升级、创建副本、暂停上线任务,恢复上线任务,回滚到以前某一版本(成功/稳定)的Deployment等功能,在某种程度上,Deployment可以帮我们实现无人值守的上线,大大降低我们的上线过程的复杂沟通、操作风险。



    Deployment的使用场景

     下面是Deployment的典型用例:

    • 使用Deployment来启动(上线/部署)一个Pod或者ReplicaSet
    • 检查一个Deployment是否成功执行
    • 更新Deployment来重新创建相应的Pods(例如,需要使用一个新的Image)
    • 如果现有的Deployment不稳定,那么回滚到一个早期的稳定的Deployment版本
    • 暂停或者恢复一个Deployment

     

    kind: 定义的对象: Replicationcontroller,  ReplicaSet  Deployment 区别

    Replicationcontroller 的升级版是 ReplicaSet , ReplicaSet支持基于集合的 Label selector, 而RC只支持基于等式的 Lable select

    Deployment其实就是内部调用 ReplicaSet.

    DaemonSet 根据标签指定pod 在那个服务器上运行,需要与nodeselect 公用。

    configMap 设置环境变量

     

    server定义的selector 与 Deployment 中的 template 的 lables 对应

    复制代码
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: tomcat-deployment
    spec:
      replicas: 3
      template:
        metadata:
          labels:
            app: tomcat
            tier: frontend
        spec:
          containers:
          - name: tomcat
            image: docker.cinyi.com:443/tomcat
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: tomcat-server
    spec:
      ports:
      - port: 11111   # cluster IP 的端口
        targetPort: 8080  # container容器的端口
      selector:
        tier: frontend
    复制代码

     

    外部系统访问service 问题

    kubernetes 中三种IP 包括

    复制代码
    1. NodeIP   node节点的IP地址
    2. PodIP     pod的IP地址
    3. clusterIP   service的IP地址
    
    nodeIP 是kubernetes集群中每个节点的物理网卡的IP地址, client 访问kubernetes集群使用的IP地址
    
    Pod ip地址 是更具创建的网络类型,网桥分配的IP地址,
    
    clusterIP 是一个虚拟的IP, cluster ip 仅作用于kubernetes service 这个对象, 是由kubernetes管理和分配ip地址,源于cluster ip地址池
    [root@kubernetes nginx]# vim /etc/kubernetes/apiserver
    # Address range to use for services
    KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"
    
    cluster IP 无法ping通, 因为没有一个 实体网络对象 响应
    
    cluster ip 只能结合 service port 组成一个具体的通信接口,单独的cluster IP不具备tcp/ip通信基础,

    如果 pod 对外访问,需要在servcie 中 指定 type 为 NodePort


    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: tomcat-deployment
    spec:
      replicas: 3
      template:
        metadata:
        labels:
          app: tomcat
          tier: frontend
    spec:
      containers:
      - name: tomcat
        image: docker.cinyi.com:443/tomcat
      ports:
      - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: tomcat-server
    spec:
      type: NodePort
      ports:
      - port: 11111 
        targetPort: 8080
        nodePort: 30001
      selector:
        tier: frontend

     

     

    root@kubernetes nginx]# kubectl describe service tomcat-server
    Name: tomcat-server
    Namespace:            default
    Labels:              <none>
    Selector:             tier=frontend
    Type:                NodePort
    IP:                10.254.222.139        #cluster IP 的地址
    Port:                <unset> 11111/TCP    #cluster IP 的端口
    NodePort:             <unset> 30001/TCP     # nodeport 的端口
    Endpoints:            10.0.223.3:8080,10.0.224.2:8080,10.0.225.2:8080   #容器的服务端口
    Session Affinity:        None
    No events.

     

    访问node IP + node port ,可以访问页面

     

    nodeport 并没有完全解决外部访问service 的问题, 比如负载均衡问题,如果有10 pod 节点, 如果是用谷歌的GCE公有云,那么可以把 service  type=NodePort 修改为 LoadBalancer.

     

     

    2 通过设置pod(daemonset) hostNetwork=true, 将pod中所有容器的端口号直接映射到物理机上, 设置hostNetwork=true的时候需要注意,如果不指定hostport,默认hostport 等于containerport, 如果指定了hostPort, 则hostPort 必须等于containerPort的值。

     

    复制代码

     

     

     deployment创建部署

    复制代码
    [root@docker ~]# cat  test_deployment.yaml

    apiVersion: extensions/v1beta1 kind: Deployment metadata: name: my-nginx spec: replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: docker.cinyi.com:443/senyint/im-web ports: - containerPort: 80
    复制代码

     

    复制代码
    1. 创建
    [root@docker ~]# kubectl create -f /root/test_deployment.yaml

    2. 查看状态
    $ kubectl get deployments
    NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    my-nginx           3         0         0            0           1s

    DESIRED 期望的副本数
    CURRENT 当前副本数
    UP-TO-DATA 最新副本数
    AVALLABLE 可用副本数

    3. 更新部署(镜像升级)
    (1)把image镜像从 docker.cinyi.com:443/senyint/nginx 升级到 docker.cinyi.com:443/senyint/im-web
    [root@docker ~]# kubectl set image deployment/my-nginx nginx=docker.cinyi.com:443/senyint/im-web

     

    (2) 直接使用edit 修改
    [root@docker ~]# kubectl edit deployment/my-nginx

    4.扩展副本数
    [root@docker ~] kubect scale deployment my-nginx --replicas=10

    5.api
     /apis/extensions/v1beta1/namespaces/default/deployments/my-nginx
    复制代码

      

     

     ReplicationController创建部署

    复制代码
    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: im-web
      namespace: test
    spec:
      replicas: 3
      template:
        metadata:
          labels:
            name: im-web
        spec:
          volumes:
          - name: workdir
            hostPath:
              path: "/data/log/im-web"
          containers:
          - name: im-web
            image: docker.cinyi.com:443/senyint/im-web:latest
            ports:
            - containerPort: 80
            volumeMounts:
            - name: workdir
              mountPath: /data/tomcat/logs
    复制代码
    复制代码
    扩容副本
    [root@docker1 ~]#  kubectl  scale rc im-web --namespace=test --replicas=5
    
    滚动升级
    [root@docker1 ~]# kubectl rolling-update im-web --image=docker.cinyi.com:443/senyint/im-web:2017-03-21_10_12

    api
    /api/v1/namespaces/test/replicationcontrollers/im-web
    复制代码

     

     

     

     

    kubernetes volume(存储卷)

    volume 是pod中能够被多个容器访问的共享目录, volume 定义在pod上,然后被一个pod里的多个容器挂载到具体的文件目录下,其实volume与pod的声明周期相同,与容器的生命周期无关系,

    kubernetes 支持多种类型的volume,如:glusterfs  ceph等分布式文件系统

     

    复制代码
    1.emptyDir:

    apiVersion: extensions/v1beta1 kind: Deployment metadata: name: tomcat-deployment apiVersion: extensions/v1beta1 kind: Deployment metadata: name: tomcat-deployment spec: replicas: 3 template: metadata: labels: app: tomcat tier: frontend spec: volumes: - name: workdir emptyDir: {} containers: - name: tomcat image: docker.cinyi.com:443/tomcat ports: - containerPort: 80 volumeMounts: - name: workdir mountPath: /opt --- apiVersion: v1 kind: Service metadata: name: tomcat-server spec: type: NodePort ports: - port: 11111 targetPort: 8080 nodePort: 30001 selector: tier: frontend

    emptyDir volume是在pod 分配到node是创建的,初始内容为空,并且无需指定宿主机上的对应的目录文件,当pod从node上移除时,emptydir中的数据也会永久被删除,目前emptyDir无法控制介质种类

    emptpdir 的一些用途如下:
    1. 临时空间,例如用于某些应用程序运行时所需的临时目录,且无须永久保修
    2. 长时间任务的中间过程checkpoint 的临时保存目录
    3. 一个容器需要从另一个容器中获取数据的目录。
    复制代码
    复制代码
    2. hostPath 为在pod上挂载宿主机上的文件或者目录,

    volumes:
    - name: "storage"
    hostPath:
    path: "/data"
    -------------------

    apiVersion: extensions/v1beta1 kind: Deployment metadata: name: tomcat-deployment spec: replicas: 3 template: metadata: labels: app: tomcat tier: frontend spec: volumes: - name: workdir hostPath: path: "/data" containers: - name: tomcat image: docker.cinyi.com:443/tomcat ports: - containerPort: 80 volumeMounts: - name: workdir mountPath: /opt #把宿主机/data目录挂载到容器的/opt目录下 --- apiVersion: v1 kind: Service metadata: name: tomcat-server spec: type: NodePort ports: - port: 11111 targetPort: 8080 nodePort: 30001 selector: tier: frontend
    复制代码

     

    3. gcePersistentDisk google云盘

    4.awsEasticblockStore 亚马逊云盘

    5 nfs, 使用nfs网络文件服务器提供的共享目录存储数据时,需要部署一个nfs server,定义nfs类型volume 如:

    复制代码
            volumeMounts:
            - name: workdir
              nfs:
    server: nfs-server
    path: "/"
    复制代码

    6. 其他类型的volume

    iscsi: 使用iscsi存储设备上的目录挂载到pod上。
    flock: 使用flocker来管理存储卷
    glusterfs: 使用glusterfs分布式文件系统
    等等.....

     

    Namespace 命名空间

    复制代码
     
     

    Namespace 在很多情况下用于多租户的资源隔离,Namespace通过将集群内部的资源对象“分配”到不通的Namespace中, 形成逻辑上的分组的不同项目,小组或者 用户组,便于不同的分组在共享使用这个集群的资源的同时还能被分别管理。

     
     


    kubernetes集群在启动后,会创建一个 default 的 namespace,

     
     

    [root@kubernetes nginx]# kubectl get namespace
    NAME STATUS AGE
    default Active 7d
    kube-system Active 7d

     
     


    如果不特别指明namespace,则用户创建的 pod rc service 都将被系统创建到defalut中



    #创建fengjian20170221 的命名空间
    apiVersion: v1 kind: Namespace metadata: name: fengjian20170221
    --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: tomcat-deployment namespace: fengjian20170221 spec: replicas: 3 template: metadata: labels: app: tomcat tier: frontend spec: volumes: - name: workdir hostPath: path: "/data" containers: - name: tomcat image: docker.cinyi.com:443/tomcat ports: - containerPort: 80 volumeMounts: - name: workdir mountPath: /opt --- apiVersion: v1 kind: Service metadata: name: tomcat-server spec: type: NodePort ports: - port: 11111 targetPort: 8080 nodePort: 30001 selector: tier: frontend

    [root@kubernetes nginx]# kubectl get namespace
    NAME        STATUS      AGE
    default       Active      7d
    fengjian20170221 Active      2m
    kube-system     Active      7d

     

    [root@kubernetes nginx]# kubectl get pods --namespace=fengjian20170221
    NAME                   READY    STATUS    RESTARTS AGE
    tomcat-deployment-2750437860-4no2f 1/1    Running    0      5m
    tomcat-deployment-2750437860-mmk4b 1/1    Running    0      5m
    tomcat-deployment-2750437860-yb8u2 1/1    Running    0      5m

    复制代码

     

    guestbook 示例:

     

    3个php, 1个redis主 ,2 个redis从

    复制代码
    [root@kubernetes guestbook]# vim redis-master.yaml 
    
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: redis-master
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: redis-master
        spec:
          containers:
          - name: redis-master
            image: docker.cinyi.com:443/kubeguide/redis-master
            ports:
            - containerPort: 6379
            env:
            - name: hostname
              value: fengjian
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: redis-master
    spec:
      ports:
      - port: 6379
        targetPort: 6379
      selector:
        app: redis-master
    
    #########################
    
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: redis-slave
    spec:
      replicas: 2
      template:
        metadata:
          labels:
            app: redis-slave
        spec:
          containers:
          - name: redis-slave
            image: docker.cinyi.com:443/kubeguide/guestbook-redis-slave
            ports:
            - containerPort: 6379
            env:
            - name: GET_HOSTS_FROM
              value: env
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: redis-slave
    spec:
      ports:
      - port: 6379
        targetPort: 6379
      selector:
        app: redis-slave
    
    
    ############################
    
    [root@kubernetes guestbook]# vim frontend-php.yaml 
    
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: frontend-server
    spec:
      replicas: 2
      template:
        metadata:
          labels:
            app: frontend-server
        spec:
          containers:
          - name: frontend-server
            image: docker.cinyi.com:443/kubeguide/guestbook-php-frontend
            ports:
            - containerPort: 80
            env:
            - name: GET_HOSTS_FROM
              value: env
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: frontend-server
    spec:
      type: NodePort
      ports:
      - port: 80
        targetPort: 80
        nodePort: 30001
      selector:
        app: frontend-server

    [root@kubernetes guestbook]# kubectl   create  -f redis-master.yaml -f redis-slave.yaml  -f frontend-php.yaml

    [root@kubernetes guestbook]# kubectl  get service

      

     

     访问 nodeIP+端口, 可以访问出程序页面, 

     
     
    复制代码

     

    Pod 声明周期和重启策略

    复制代码
    状态        描述
    Pending      API server 已经创建该Pod,但pod 内还有一个或多个容器的镜像还有创建,包括正在下载镜像的过程
    Running      pod内的所有容器均已创建,且至少有一个容器处于运行状态,正在启动状态或正在重启状态。
    Successed     Pod内所有容器均成功执行退出,且不会重启
    Failed       Pod内所有容器均已退出,但至少一个容器退出为失败状态
    Unknown      由于某种原因无法获取该pod的状态,可能由于网络问题
    复制代码

     

    Pod重启策略(restartpolicy) 应用于pod内的所有容器,并且仅在pod所处的node上由kubelet进行判断和重启操作,

    复制代码
    pod 的重启策略包括always、 onfailure 、 Never, 默认为always.

    always: 懂容器失效时,有kubulet自动重启该容器
    onfailure: 当容器终止运行且退出码不为0,有kubulet 自动重启容器
    never: 不论容器运行状态如何,kubelet都不会重启该容器。

    复制代码

     

     

    Pod扩容和缩容

    在生产环境中,经常会遇到某个服务需要扩容的场景,也可能会遇到由于资源紧张或工作负载降低减少服务实例的场景,可以使用 RC 的 scale机制操作

     

    复制代码
    [root@kubernetes guestbook]# kubectl get pods
    NAME                               READY     STATUS    RESTARTS   AGE
    frontend-server-3958566729-0fwym   1/1       Running   0          2h
    frontend-server-3958566729-dw937   1/1       Running   0          2h
    redis-master-1081272834-nyjra      1/1       Running   0          2h
    redis-slave-3198086074-0ijyl       1/1       Running   0          2h
    redis-slave-3198086074-6vwya       1/1       Running   0          2h
    [root@kubernetes guestbook]# kubectl scale deployment frontend-server --replicas=1    #replicas 副本数变成1个
    deployment "frontend-server" scaled
    [root@kubernetes guestbook]# kubectl get pods
    NAME                               READY     STATUS    RESTARTS   AGE
    frontend-server-3958566729-0fwym   1/1       Running   0          2h
    redis-master-1081272834-nyjra      1/1       Running   0          2h
    redis-slave-3198086074-0ijyl       1/1       Running   0          2h
    redis-slave-3198086074-6vwya       1/1       Running   0          2h
    复制代码

     

    静态pod

    是由kubelet进行管理的,仅存在于特定的node上的pod, 他们不能功过API server进行管理,无法于ReplicationController,Deployment或者DaemonSet关联

    kebelet守护进程监控它,并在崩溃时重启它。 静态pod 总是绑定到一个kubulet守护程序上,并且总是运行在同一个节点上。

     

    创建静态pod的两种方式, 1. 配置文件 ,2.http

     

    复制代码
    (1)、创建一个yaml文件,并且放置到一个文件夹中/etc/kubelet.d/

    [root@docker225 kubelet.d]# mkdir /etc/kubelet.d/
    [root@docker225 kubelet.d]# cat static-web.yaml

    apiVersion: v1 kind: Pod metadata: name:
    static-web labels: role: myrole spec: containers: - name: web image: nginx ports: - name: web containerPort: 80 protocol: TCP

    (2) 修改 /etc/kubernetes/kubelet 配置文件,最后一行添加 静态pod的yaml文件的路径。
    KUBELET_ARGS="--pod-manifest-path=/etc/kubelet.d/"
    (3)重启kulelet 服务
    systemctl restart kubelet.service

      (4) 删除静态pod, yaml文件去掉后,会自动删除

       mv static-web.yaml     /root/static-web.xml

    复制代码

     

     

    configmap

    许多应用程序需要通过配置文件,命令行参数和环境变量的组合进行配置。这些配置工件应该与映像内容解耦,以便保持容器化应用程序可移植。ConfigMap API资源提供了使用配置数据注入容器的机制,同时保持容器与Kubernetes无关

    应用部署的一个最佳实践是将应用所需的配置信息与程序进行分离,这样可以使得应用程序被更好的复用,通过不同的配置也能实现更灵活的功能,将应用打包为镜像后,可以通过环境变量或者外挂文件的方式在创建容器时进行配置注入,

    在大规模容器集群的环境中,对多个容器进行不同的配置将变得非常负责, kubernetes提供了一种统一的集群配置管理方案

     

    configmap 供容器使用的典型方案如下:

    1. 生成为容器内的环境变量

    2. 设置容器启动命令的启动参数

    3. 以volume的形式挂载为容器内部的文件或者目录

    4: 注意必须先创建 configMap, 然后pod 才能创建,如果已经创建的pod,升级,环境变量无法找到,

    一定要做好提前规划。

    复制代码
    生成为容器内的环境变量

    [root@kubernetes configmap]# cat cm-appenv.yaml 

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: testenv
      namespace: test
    data:
      mysql_server: 192.168.20.131
      redis_server: 192.168.20.116
      mongo_server: 192.168.20.116

     
    支持所有的kind类型:如下: china.yaml
    

    apiVersion: v1
    kind: Service
    metadata:
      name: china
      labels:
        app: china
    spec:
      ports:
      - port: 80
      selector:
        app: china
    ---
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: china
      namespace: test
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: china
        spec:
          containers:
          - name: china
            image: docker.cinyi.com:443/senyint/im-web
            ports:
            - containerPort: 80
            env:
            - name: mysql_server
              valueFrom:
                configMapKeyRef:
                  name: testenv
                  key: mysql_server
            - name: redis_server
              valueFrom:
                configMapKeyRef:
                  name: testenv
                  key: redis_server
            - name: mongo_server
              valueFrom:
                configMapKeyRef:
                  name: testenv
                  key: mongo_server



    [root@kubernetes configmap]# kubectl  create -f cm-appenv.yaml -f china.yaml

    [root@kubernetes configmap]# kubectl  get pods --all-namespaces -o wide

    登陆到pod中,查看env环境变量

      [root@kubernetes configmap]# kubectl exec -it china-3221241881-rlr8w --namespace=test bash

      [root@china-3221241881-rlr8w /]# env | grep -i server

      

      redis_server=192.168.20.116
      mysql_server=192.168.20.131
      mongo_server=192.168.20.116
      mysql-server=192.168.20.131

    复制代码

     

    configmap使用 volumeMount模式

     

    复制代码
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: special-config
      namespace: default
    data:
      special.how: very
      special.type: charm
    ---
    
    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-test-pod
    spec:
      containers:
        - name: test-container
          image: docker.cinyi.com:443/busybox
          command: [ "/bin/sh", "-c", "cat /etc/config/special.how" ]
          volumeMounts:
          - name: config-volume
            mountPath: /etc/config
      volumes:
        - name: config-volume
          configMap:
            name: special-config
      restartPolicy: Never
    复制代码

     

     

    DNS服务

    为了能够通过服务的名字在集群内部进行服务的相互访问,需要创建一个虚拟的dns服务来完成服务名到clusterIP的解析,

    复制代码
    kubernetes 提供的虚拟dns服务器名为skydns,是由4个组件组成
    1. etc: dns存储
    2. kube2sky: 将kubernetes master 中的service 注册到etcd
    3. skydns 提供dns域名解析服务
    4. healthz: 提供对skydns服务的健康检查功能
    复制代码

     

    创建skydns的yaml文件

    复制代码
    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: kube-dns-v8
      namespace: kube-system
      labels:
        k8s-app: kube-dns
        version: v8
        kubernetes.io/cluster-service: "true"
    spec:
      replicas: 1
      selector:
        k8s-app: kube-dns
        version: v8
      template:
        metadata:
          labels:
            k8s-app: kube-dns
            version: v8
            kubernetes.io/cluster-service: "true"
        spec:
          containers:
          - name: etcd
            #image: gcr.io/google_containers/etcd:2.0.9
            image: index.tenxcloud.com/google_containers/etcd:2.0.9
            resources:
              limits:
                cpu: 100m
                memory: 50Mi
            command:
            - /usr/local/bin/etcd
            - -data-dir
            - /var/etcd/data
            - -listen-client-urls
            - http://127.0.0.1:2379,http://127.0.0.1:4001
            - -advertise-client-urls
            - http://127.0.0.1:2379,http://127.0.0.1:4001
            - -initial-cluster-token
            - skydns-etcd
            volumeMounts:
            - name: etcd-storage
              mountPath: /var/etcd/data
          - name: kube2sky
            #image: gcr.io/google_containers/kube2sky:1.11
            image: index.tenxcloud.com/google_containers/kube2sky:1.11
            resources:
              limits:
                cpu: 100m
                memory: 50Mi
            args:
            # command = "/kube2sky"
            - -domain=cinyi.com
            - -kube_master_url=http://192.168.20.226:8080
          - name: skydns
            #image: gcr.io/google_containers/skydns:2015-03-11-001
            image: index.tenxcloud.com/google_containers/skydns:2015-03-11-001
            #image: index.tenxcloud.com/google_containers/skydns:2015-10-13-8c72f8c
            resources:
              limits:
                cpu: 100m
                memory: 50Mi
            args:
            # command = "/skydns"
            - -machines=http://localhost:4001
            - -addr=0.0.0.0:53
            - -domain=cinyi.com
            ports:
            - containerPort: 53
              name: dns
              protocol: UDP
            - containerPort: 53
              name: dns-tcp
              protocol: TCP
          volumes:
          - name: etcd-storage
            emptyDir: {}
          dnsPolicy: Default # Don't use cluster DNS.
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: kube-dns
      namespace: kube-system
      labels:
        k8s-app: kube-dns
        kubernetes.io/cluster-service: "true"
        kubernetes.io/name: "KubeDNS"
    spec:
      selector:
        k8s-app: kube-dns
      clusterIP: 10.254.0.2 
      ports:
      - name: dns
        port: 53
        protocol: UDP
      - name: dns-tcp
        port: 53
        protocol: TCP

    复制代码
    复制代码
    2. 修改每台node 上的 kubelet启动参数
    [root@docker223 ~]# cat /etc/kubernetes/kubelet 
    ###
    # kubernetes kubelet (minion) config
    
    # The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
    KUBELET_ADDRESS="--address=0.0.0.0"
    
    # The port for the info server to serve on
    # KUBELET_PORT="--port=10250"
    
    # You may leave this blank to use the actual hostname
    KUBELET_HOSTNAME="--hostname-override=192.168.20.223"
    
    # location of the api-server
    KUBELET_API_SERVER="--api-servers=http://192.168.20.226:8080"
    
    # pod infrastructure container
    KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=docker.cinyi.com:443/rhel7/pod-infrastructure:latest"
    #KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
    
    # Add your own!
    KUBELET_ARGS="--pod-manifest-path=/etc/kubelet.d/ --cluster_dns=10.254.0.2 --cluster_domain=cinyi.com"
    复制代码

     

     DNS工作原理解析:

    1. kube2sky通过调用kubernetes master 的API 获取集群中所有service的信息,并且持续监控新的service 的生成,然后写入etcd中

    查看etcd中存储的service 信息

    复制代码
    [root@kubernetes nginx]# kubectl exec kube-dns-v8-98n35 -c etcd --namespace=kube-system etcdctl ls /skydns/com/cinyi
    /skydns/com/cinyi/default
    /skydns/com/cinyi/svc
    /skydns/com/cinyi/kube-system

    查看tomcat1 服务对应的键值:

    [root@kubernetes nginx]# kubectl exec kube-dns-v8-98n35 -c etcd --namespace=kube-system etcdctl get /skydns/com/cinyi/default/tomcat1
    {"host":"10.254.100.145","priority":10,"weight":10,"ttl":30,"targetstrip":0}

    复制代码

     

    2. kubelet启动参数设置了(--cluster_dns),kubelet会在每个创建的pod中设置dns解析配置 /etc/resolv.conf

    1
    2
    3
    4
    5
    6
    [root@docker223 ~]# docker exec -it 2ff /bin/bash
    [root@my-nginx-335071150-a8mak nginx-1.11.2]# cat /etc/resolv.conf
    search  default .svc.cinyi.com svc.cinyi.com cinyi.com
    nameserver 10.254.0.2
    nameserver 114.114.114.114
    options ndots:5

      

    3.应用程序能够通过网站域名进行访问。

    复制代码
    [root@my-nginx-335071150-a8mak nginx-1.11.2]# nslookup tomcat1
    Server:        10.254.0.2
    Address:    10.254.0.2#53
    
    Name:    tomcat1.default.svc.cinyi.com
    Address: 10.254.100.145
    复制代码

     

    例子:查看所有的service 服务

     

     

    进入到 pod容器中后 ping kubernetes-dashboard.kube-system 的server,不同,但是可以解析到IP地址

     

    使用telnet kubernetes-dashboard.kube-system  80端口,是通的,

     

    结论:service 通过内部IP(虚IP),可以进行通信,但是不能ping通。

     

     

    遇到的问题:

    1. ingress  如果使用不同namespace,需要使用2个yaml文件

    2. 配置一个nginx pod,hostNetwork=true的情况下,进入pod中 dns无法解析到其他services,所以直接采用nginx反向代理service方式行不通。 可以是使用问题6的方式,暴露service的nodePort端口。

    3. 容器的hosts: 在dockerfile中,使用add host /etc/,命令,容器启动后,host还是被覆盖

    4. 使用configMap,设置环境变量方式,但是一定要提前规划好,当pod已经创建,再修改configmap文件, 添加环境变量 , 启动的pod,环境变量不启用,需要删除pod,重新创建。

    5. deployment 与 ReplicationController api不同,升级方法不同

    6. DaemoSet类型 实现高可用,需要删除 replicas 参数, 并且设置nodeSelector,只是label, 最后,在node上引用label,kubectl label node docker role=master

    7. 所有操作都是用API,与jenkins结合使用。

    8. k8s 1.5.3以后 skydns 已经取消, 新的 Kubernetes DNS pod拥有3个容器 kubedns,dnsmasq和一个名为healthz的健康检查。kubedns进程监视Kubernetes主服务和端点的更改,并维护内存中查找结构来服务DNS请求。dnsmasq容器添加DNS缓存以提高性能。healthz容器在执行双重健康检查(对于dnsmasq和kubedns)时提供单个健康检查端点。

    展开全文
  • C/S与B/S的比较: 服务器与Web服务器的差别 浏览器与客户端的差别 浏览器与Web服务器的作用与关系 长连接与短连接 无状态协议 无状态与KeepAlive的关系 通过Socket通信看TCP与UDP的面向连接/面向非连接 扩展...
  • C/S、B/S,前端后端

    千次阅读 2018-05-23 20:32:16
    CS即Client/Server(客户机/服务器)结构,C/S结构在技术上很成熟,它的主要特点是交互性强、具有安全的存取模式、网络通信量低、响应速度快、利于处理大量数据。但是该结构的程序是针对性开发,变更不够灵活,维护...
  • 3、在脚本 install-etcd-flannel-k8s.sh 中设置 3台的IP; 4、做好master到两台node的免密登陆; 5、将安装包放在master上,直接执行bash install-etcd-flannel-k8s.sh 即可; 6、docker使用了aliyun的镜像库安装,2...
  • 它结合了AD-Capital-K8s-V1和AD-Capital-K8s-Approval的部署资源,为本实验的“线束”部分做好了准备。 Rookout -这是AD-Capital应用程序的完全独立的版本,可用于本练习的“交接”部分。 AD-Capital-K8s-...
  • C/S、B/S及三层结构

    千次阅读 2009-07-07 09:58:00
    C/S、B/S及三层结构By rk999888 发表于 2006-6-17 17:46:07 B/S结构跟C/S结构的区别所谓B/S结构,就是只安装维护一个服务器(Server),而客户端采用浏览器(Browse)运行软件,即浏览器/服务器结构。 B/S结构的...
  • 基于k8s的zookeeper集群

    2021-08-20 17:39:37
    基于k8s的zookeeper集群,已做好亲和力和反亲和。并使用了hostpath的方式。也可以自行改为pv-pvc
  • S1700系列交换机快速安装指南: 此为A级产品,在生活环境中,该产品可能会造成无线电干扰,在这种情况下,可能需要用户对其干扰 采取切实可行的防护措施。 安装前请做好防静电保护措施,如佩戴防静电手套或防静电...
  • 题目:  定义一个带参的宏(或者模板函数),带有三个参数,第一个参数为类型,后两个参数的值互换,并写出程序,输入两个数作为使用宏时... s=m, m=n, n=s;} int main() { short int i1,i2; double d1,d2; l
  • 详细的s5830刷机教程。刷机有风险,各位需谨慎。做好备份
  • 文章旨在做好高校开发建设,实现大学英语在线考试,在大学英语教学中做好机考的应用,将大学英语标准化考试全面促进。通过提出一种B/S结构的英语标准化考试系统,通过分析系统需求,注重功能需求和安全性能需求分析...
  • = k8s_master IP .1 = 192.168 .2 .1 # ClusterIP 地址 IP .2 = 10.211 .55 .10 # master IP地址 生成apiserver证书 openssl req -new -key server . key -subj "/CN=10.211.55.10" ...
  • k8s技术预研11--kubernetes网络原理

    万次阅读 2018-06-11 08:45:18
    关于k8s网络,我们通常有以下问题需要回答:k8s的网络模型是什么Docker背后的网络基础是什么Docker自身的网络模型和局限k8s的网络组件之间是怎么通信的外部如何访问k8s的集群有哪些开源的组件支持k8s的网络模型接...
  • 上一篇有写到怎样将一个普通的springboot的jar包,制作成docker镜像,并push到镜像...这里我们介绍下,怎样将你做好的容器纳入K8S的统筹管理之下;let`s go 1、首先你要有一个k8s环境,例如 kubectl version Cl...
  • 本文是《k8s自定义controller三部曲》的第二篇,我们一起来实战如何将controller所需的informer、client等代码通过工具自动生成
  • )diskboot.S位于目录boot/i386/pc/,最终生成diskboot.img。这部分指令被加载到0x8000~0x81FF。diskboot.img加载GRUB内核到0x8200开始的内存位置,并将系统控制权交给GRUB内核。用到的BIOS例程和boot.S中相同。因此...
  • 高通8953调试I2S小记

    千次阅读 2019-03-28 18:14:30
    在调通i2s后,发现设备做蓝牙免提时没有声音。后来发现QUIN通路高通竟然没调试过蓝牙免提,这部分代码都没有!经过一番折腾。总算把驱动搞好了。但在实际过程中老是报如下错误: [ 2018.164783] msm_pcm_routing_...
  • Matlab S-Function详解

    万次阅读 多人点赞 2017-10-24 22:00:51
    Part I: ... s函数可以用matlab、C、C++、Fortran、Ada等语言来写, 这儿我只介绍怎样用matlab语言来写吧(主要是它比较简单) < xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:offic
  • 在AWS中国区使用kops安装k8s完全指南

    千次阅读 2018-04-02 21:14:30
    因为一些众所周知的原因,AWS中国区并没有k8s集群,因此我们需要自己安装k8s。而k8s官方提供了一个工具kops来帮助我们快速地在AWS上创建k8s集群。下面是使用kops在AWS创建集群的详细过程。 安装kops (Binaries) ....
  • 本文同步发于原作者的blog: http://www.vingel.com/blog/43      这本书我已经买了三个星期,一直...我得到的关于《Unix编程艺术》最深的感想就是:Unix中无所不在的K.I.S.S(Keep It Simple, Stupid)原则。 显然,U
  • # cat /etc/hosts 7)web端访问jenkins界面 8)创建一个jenkins_project项目,并编辑配置 9)在jenkins的后端准备好自动化部署脚本k8s_auto_deploy.sh,事先做好公私钥认证,使得jenkins能够访问k8s-master-1 [root@...
  • BootLoader还涉及到许多硬件相关的知识,对于普通的嵌入式开发板,它又是不可跳过的步骤,所以做好它的移植工作是必须的,对于后续的开发工作也是有益的。U-Boot是当前比较流行、功能强大的BootLoader,它操作简便,...
  • 规划好3台主机: ip地址 主机名 角色 192.168.193.101 k8s-master master 192.168.193.102 k8s-node-1 worker 192.168.193.103 k8s-node-2 worker 1、分别修改主机名、IP地址和hosts文...
  • 这个是B/S未登录的效果 这个是C/S里调用单点登录B/S的代码部分 这个是C/S里调用单点登录B/S的运行效果,自动登录到B/S系统了,B/S系统也识别了当前用户了,SUID每次都会重新生成,所以不用过多担心。 将权限...
  • 我们在之前的文章中 已经了解了 spark支持的模式,其中一种就是 使用k8s进行管理。 hadoop组件—spark----全面了解spark以及与hadoop的区别 是时候考虑让你的 Spark 跑在K8s 上了 spark on k8s的优势–为什么要把...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 148,398
精华内容 59,359
关键字:

如何做好s