手把手教你使用Travis CI实现持续部署

持续集成、持续交付、持续部署。听起来就像是在大型软件工程,高端开发项目组里才会应用到的概念。其实不然,通过运用一些开源免费的工具和平台,不管是你的个人博客还是side-projects都能够享受到开发任务自动化的便利。

这次我们的教程主要会分为以下几步:

  1. 注册并设置Travis CI
  2. 在开发服务器(或本地)上生成密匙并与部署服务器互信
  3. 安装Ruby 2.0以上版本并安装travis的命令行工具
  4. 编写测试并在项目中配置travis
  5. 编写travis自动部署脚本
  6. 提交代码检验运行

本教程以最基础的部署php站点为例(其实与部署的应用本身关系不大,不管是NodeJS还是Hexo一类的静态站点生成全部都大同小异,只需要替换自动执行的命令就可以了)

注册并设置Travis CI

先打开Travis CI官网,点击右上角使用Github登录的按钮(这里假设读者已经注册并掌握Github的基本使用了)

登录成功后,你应该会看到和下图差不多的页面,按照提示进行操作:

你可以打开先看一眼你在Travis CI上项目的页面,不过现在肯定是空空如也一片,我们在官网上需要进行的操作暂且到此为止。

在开发服务器(或本地)生成密匙并与部署服务器互信

不管是本地还是开发服务器,这里已经默认了你的开发环境是Linux/类Unix系统,不要问我Windows该怎么办,Win10可以安装Ubuntu子系统,当然你要是不觉得蛋疼也可以下载一些类似ssh key generator的软件。

这里其实只需要用到两个命令。

首先在本地或开发服务器上生成密匙,在命令行里输入:

ssh-keygen -t rsa

之后只需要按照提示操作,你大概会看到类似下面的内容:

# 来自Digital Ocean
ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/demo/.ssh/id_rsa): 
# 这里的密码一定要留空袄
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/demo/.ssh/id_rsa.
Your public key has been saved in /home/demo/.ssh/id_rsa.pub.
The key fingerprint is:
4a:dd:0a:c6:35:4e:3f:ed:27:38:8c:74:44:4d:93:67 demo@a
The key's randomart image is:
+--[ RSA 2048]----+
|          .oo.   |
|         .  o.E  |
|        + .  o   |
|     . = = .     |
|      = S = .    |
|     o + = +     |
|      . o + o .  |
|           . o   |
|                 |
+-----------------+

接下来你需要将你开发环境生成的密匙拷贝到你的部署服务器上。之所以进行这一步是为了实现免密码登录ssh,因为travis-ci自动执行命令是不支持交互式输入密码的。

同样只需要一个命令:

ssh-copy-id <登录部署服务器用户名>@<部署服务器地址>
# 如果ssh默认端口不是22
ssh-copy-id <登录部署服务器用户名>@<部署服务器地址> -p <部署服务器ssh端口>
# 示例
ssh-copy-id travis@123.123.123.123 -p 12345

接下来也同样按提示操作,第一次输入密码登录完成后,就可以使用密匙测试免密登录啦,当然为了安全起见,记得这里专门为持续部署新建一个权限适宜的用户袄。

安装Ruby 2.0以上版本并安装travis的命令行工具

简单的apt-get install ruby并不能顺利解决问题,travis命令行工具依赖ruby2.0以上的版本。

这个地方其实是一个坑,我想大部分同学和我一样都是使用Ubuntu系统,默认使用apt-get install ruby2.0安装的事实上是1.9版本,这特么就很尴尬了。

所以我们不得不下载源码手动编译安装。如果你的开发环境之前安装过ruby记得先删掉:

sudo apt-get -y update
sudo apt-get -y install build-essential zlib1g-dev libssl-dev libreadline6-dev libyaml-dev
cd /tmp
# 由于众所周知的网络原因,此处可能需要使用到http_proxy
wget http://ftp.ruby-lang.org/pub/ruby/2.1/ruby-2.1.5.tar.gz 
tar -xvzf ruby-2.1.5.tar.gz
cd ruby-2.1.5/
./configure --prefix=/usr/local
make
sudo make install

如果嫌麻烦你可以把上述命令保存成一个.sh文件一键执行。安装完成后使用ruby -v验证一下版本。

之后再运行:

# 由于众所周知的网络原因,此处可能需要使用到http_proxy
gem install travis

如果网络实在太差,可以使用RubyGems 镜像

gem sources --add https://gems.ruby-china.org/
gem sources --remove https://rubygems.org/
gem sources --remove http://rubygems.org/
gem sources -l

安装完成后,切换到你开发环境的项目目录下,运行:

travis login

根据提示,输入你刚刚用于travis-ci网站登录的Github账户名及密码。

编写测试并在项目中配置travis

下面我以使用PHPUnit对PHP进行测试为例对持续部署项目进行配置:

其实你用mocha测试JS什么的也是一样的。

<?php
//假如你的PHP项目中并没有安装PHPUnit依赖,就像我这么写吧,不要用use关键字引入,否则在travis-ci运行时会报错
class Test extends PHPUnit_Framework_TestCase
{
    public function testAutoPass()
    {
        $this->assertEquals(
            'yubolun',
            'yubolun'
        );
    }
}

之后在你的项目根目录新建一个名为.travis.yml的文件:

language: php
php:
- 5.6
before_script: composer require phpunit/phpunit
script: phpunit Test.php

前端项目也很类似:

language: node_js
node_js:
  - '6.9.5'
  - '7.5.0'
before_script: npm install
script: npm run test

以上只是举个例子,更多详细的配置内容请查阅官网文档

编写travis自动部署脚本

做好基本的项目配置之后,我们需要配置持续部署的自动运行脚本。

首先使用travis encrypt-file命令对你刚刚在开发环境生成的密匙进行加密(这样一来可以放心地将密匙保存在公开的开源项目当中)。

# 此处的--add参数表示自动添加脚本到.travis.yml文件中
travis encrypt-file ~/.ssh/id_rsa --add

之后再打开.travis.yml文件,你会看到一段类似如下内容的命令:

before_install:
  - openssl aes-256-cbc -K $encrypted_830d3b21a25d_key -iv $encrypted_830d3b21a25d_iv
    -in id_rsa.enc -out ~/.ssh/id_rsa -d

默认生成的命令可能会在/前面带转义符\,我们不需要这些转义符,手动删掉所有的转义符,否则可能在后面引发莫名的错误。

之后为了保证命令的顺利运行,我们还需要正确地设置权限和认证:

before_install:
  - openssl aes-256-cbc -K $encrypted_830d3b21a25d_key -iv $encrypted_830d3b21a25d_iv
    -in id_rsa.enc -out ~/.ssh/id_rsa -d
# 添加如下两行内容,Host后面的ip替换成你的部署服务器地址
  - chmod 600 ~/.ssh/id_rsa
  - echo -e "Host 123.123.123.123\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config

P.S.此处的配置文件只是示例啊,不要直接复制,每次生成的加密都是不一样的。

之后,也是最重要的一步,配置你执行持续部署的命令:

language: php
php:
- 5.6
before_install:
- openssl aes-256-cbc -K $encrypted_830d3b21a25d_key -iv $encrypted_830d3b21a25d_iv
  -in id_rsa.enc -out ~/.ssh/id_rsa -d
- chmod 600 ~/.ssh/id_rsa
- echo -e "Host 123.123.123.123\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
before_script: composer require phpunit/phpunit
script: phpunit Test.php
# 添加一个名为after_success的钩子,并写入你需要执行部署操作的命令
after_success:
- ssh travis@123.123.123.123 -p 12345 'cd /var/www && git pull'

在这里你可以运行任意的脚本,比方说我的项目只需要把代码pull下来就算部署完成了,其他的例如静态博客可以hexo g,或者是node应用的pm2 startup,前端项目也可以先webpack一下等等,别跑rm -rf,其他的随意。

提交代码检验运行

上述的步骤全都部署完成后,只需要使用git将你的所有改动提交到github上,travis-ci就会自动运行啦,最后别忘了登录到你的部署服务器检验一下效果袄~

至此大功告成,接下来你只需要愉快地写代码,提交Git。剩下的测试、编译、部署工作全部都会自动完成啦。

Setup Kubernetes on a Raspberry Pi Cluster easily the official way!

Kubernetesshares the pole position with Docker in the category “orchestration solutions for Raspberry Pi cluster”.However it’s setup process has been elaborate – untilv1.4 with the kubeadm announcement.With that effort, Kubernetes changed this game completely and can be up and running officially within no time.

I am very happy to announce that this blog post has been written in collaboration withLucas Käldström, an independent maintainer of Kubernetes (his story is very interesting, you can read it in aCNCF blogpost).

SwarmClusterHA

Why Kubernetes?

As shown in my recenttalk, there are many software suites available to manage a cluster of computers. There is Kubernetes, Docker Swarm, Mesos, OpenStack, Hadoop YARN, Nomad… just to name a few.

However, at Hypriot we have always been in love with tiny devices. So when working with an orchestrator, the maximum power we wanna use is what’s provided by a Raspberry Pi. Why? We have IoT networks in mind that will hold a large share in tomorrow’s IT infrastructure. At their edges, the power required for large orchestrators simply is not available.

This boundary of resources leads to several requirements that need to be checked before we start getting our hands dirty with an orchestrator:

  • Lightweight:Software should be fit on a Raspberry Pi or smaller. As proofed in my talk mentioned above, Kubernetes painlessly runs on a Raspberry Pi.
  • ARM compatible:Since the ARM CPU architecture is designed for low energy consumption but still able to deliver a decent portion of power, the Raspberry Pi runs an ARM CPU. Thanks to Lucas, Kubernetes is ARM compatible.
  • General purpose:Hadoop or Apache Spark are great for data analysis. But what if your use case changes? We prefer general purpose software that allows to runanything. Kubernetes uses a container runtime (with Docker as the 100% supported runtime for the time being) that allows to run whatever you want.
  • Production ready:Since we compare Kubernetes against a production ready Docker suite, let’s be fair and only choose equivalents. Kubernetes itself is production ready, and while the ARM port has some small issues, it’s working exactly as expected when going the official kubeadm route, which also will mature with time.

So, Kubernetes seems to be a compelling competitor to Docker Swarm. Let’s get our hands on it!

Wait – what aboutKubernetes-on-ARM?

If you followed the discussion of Kubernetes on ARM for some time, you probably know about Lucas’ projectkubernetes-on-ARM. Since the beginning of the movement to bring Kubernetes on ARM in 2015, this project has always been the most stable and updated.

However, during 2016, Lucas’ contributions have successfully been merged into official Kubernetes repositories, such that there is no point any more for using the kubernetes-on-ARM project.In fact, the features of that project are far behind of what’s now implemented in the official repos,and that has been Lucas’ goal from the beginning.

So if you’re up to using Kubernetes, please stick to the official repos now. And as of the kubeadm documentation,the following setup is considered official for Kubernetes on ARM.

At first: Flash HypriotOS on your SD cards

As hardware, take at least two Raspberry Pis and make sure they are connected to each other and to the Internet.

First, we need an operating system. Download and flashHypriotOS. The fastest way to download and flash HypriotOS on your SD cards is by using ourflash toollike so:

flash --hostname node01 https://github.com/hypriot/image-builder-rpi/releases/download/v1.4.0/hypriotos-rpi-v1.4.0.img.zip

Provision all Raspberry Pis you have like this and boot them up.

Afterwards, SSH into the Raspberry Pis with

sshpirate@node01.local

The passwordhypriotwill grant you access.

Install Kubernetes

The installation requries root privileges. Retrieve them by

sudo su -

To install Kubernetes and its dependencies, only some commands are required.First, trust the kubernetes APT key and add the official APT Kubernetes repository on every node:

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -$ echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" > /etc/apt/sources.list.d/kubernetes.list

… and then just installkubeadmon every node:

$ apt-get update && apt-get install -y kubeadm

After the previous command has been finished, initialize Kubernetes on themaster nodewith

$ kubeadm init --pod-network-cidr 10.244.0.0/16

It is important that you add the--pod-network-cidrcommand as given here, because we will useflannel. Read the next notes about flannel if you wanna know why.

Some notes about flannel: We picked flannel here because that’s the only available solution for ARM at the moment (this is subject to change in the future though).

flannel can use and is using in this example the Kubernetes API to store metadata about the Pod CIDR allocations, and therefore we need to tellKubernetesfirst which subnet we want to use. The subnet we chose here is somehow fixed, because theflannel configuration filethat we’ll use later in this guide predefines the equivalent subnet. Of course, you can adapt both.

If you are connected via WIFI instead of Ethernet, add--apiserver-advertise-address=<wifi-ip-address>as parameter tokubeadm initin order to publish Kubernetes’ API via WiFi. Feel free to explore the other options that exist forkubeadm init.

After Kubernetes has been initialized, the last lines of your terminal should look like this:

init

To start using your cluster, you need to run (as a regular user):

$ sudo cp /etc/kubernetes/admin.conf $HOME/$ sudo chown $(id -u):$(id -g) $HOME/admin.conf$ export KUBECONFIG=$HOME/admin.conf

Next, as told by that output, let all other nodes join the cluster via the givenkubeadm joincommand. It will look something like:

$ kubeadm join --token=bb14ca.e8bbbedf40c58788 192.168.0.34

After some seconds, you should see all nodes in your cluster when executing the followingon the master node:

$ kubectl get nodes

Your terminal should look like this:

k8S

Finally,we need to setup flannel as the Pod network driver. Run thison the master node:

$ curl -sSL https://rawgit.com/coreos/flannel/v0.7.1/Documentation/kube-flannel-rbac.yml | kubectl create -f -$ curl -sSL https://rawgit.com/coreos/flannel/v0.7.1/Documentation/kube-flannel.yml | sed "s/amd64/arm/g" | kubectl create -f -

Your terminal should look like this:

k8S

Then wait until all flannel and all other cluster-internal Pods areRunningbefore you continue:

$ kubectl get po --all-namespaces

Nice, it seems like they are allRunning:

show-namespaces

That’s all for the setup of Kubernetes! Next, let’s actually spin up a service on the cluster!

Test your setup with a tiny service

Let’s start a simple service so see if the cluster actually can publish a service:

$ kubectl run hypriot --image=hypriot/rpi-busybox-httpd --replicas=3 --port=80

This command starts set of containers calledhypriotfrom the imagehypriot/rpi-busybox-httpdand defines the port the container listens on at80. The service will bereplicated with 3 containers.

Next, expose the Pods in the above created Deployment in a Service with a stable name and IP:

$ kubectl expose deployment hypriot --port 80

Great! Now, let’s check if all three desired containers are up and running:

$ kubectl get endpoints hypriot

You should see three endpoints (= containers) like this:

show-endpoints

Let’ curl one of them to see if the service is up:

curl-service

The HTML is the response of the service. Good, it’s up and running! Next, let’s see how we can access it from outside the cluster!

Finally access your service from outside the cluster

We will now deploy an example Ingress Controller to manage incoming requests from the outside world onto our tiny service. Also, in this example we we’ll useTraefikas load balancer. Read the following notes if you wanna know more about Ingress and Traefik.

In contrast to Docker Swarm, Kubernetes itself does not provide an option to define a specific port that you can use to access a service. According to Lucas is this an important design decision; routing of incoming requests should be handled by a third party, such as a load balancer or a webserver, but not by the core product. The core Kubernetes should be lean and extensible, and encourage others to build tools on top of it for their specific needs.

Regarding load balancers in front of a cluster, there isthe Ingress API objectand some sampleIngress Controllers. Ingress is a built-in way of exposing Services to the outside world via an Ingress Controller that anyone can build. AnIngress ruledefines how traffic should flow from the node the Ingress controller runs on to services inside of the cluster.

First, let’s deploy traefik as load balancer:

$ kubectl apply -f https://raw.githubusercontent.com/hypriot/rpi-traefik/master/traefik-k8s-example.yaml

Label the node you want to be the load balancer. Then the Traefik Ingress Controller will land on the node you specified. Run:

$ kubectl label node <load balancer-node> nginx-controller=traefik

Lastly, create an Ingress object that makes Traefik load balance traffic on port80to thehypriotservice:

$ cat > hypriot-ingress.yaml <<EOFapiVersion: extensions/v1beta1kind: Ingressmetadata:  name: hypriotspec:  rules:  - http:      paths:      - path: /        backend:          serviceName: hypriot          servicePort: 80EOF$ kubectl apply -f hypriot-ingress.yaml

Visit the loadbalancing node’s IP address in your browser and you should see a nice web page:

curl-service

If you don’t see a website there yet, run:

$ kubectl get pods

… and make sure all hypriot Pods are in theRunningstate.

Wait until you see that all Pods are running, and a nice Hypriot website should appear!

Tear down the cluster

If you wanna reset the whole cluster to the state after a fresh install, just run this on each node:

$ kubeadm reset

In addition, it is recommended to delete some additional filesas it is mentioned here.

Optional: Deploy the Kubernetes dashboard

The dashboard is a wonderful interface to visualize the state of the cluster. Start it with:

$ curl -sSL https://rawgit.com/kubernetes/dashboard/master/src/deploy/kubernetes-dashboard.yaml | sed "s/amd64/arm/g" | kubectl create -f -

The following command provides the port that the dashboard is exposed at on every node with the NodePort function of Services, which is another way to expose your Services to the outside of your cluster:

$ kubectl -n kube-system get service kubernetes-dashboard -o template --template="{{ (index .spec.ports 0).nodePort }}" | xargs echo

Then you can checkout the dashboard on any node’s IP address on that port!

原文出处

Docker集群管理在树莓派上

随着IOT市场的火热发展,Docker天然的轻量级以及帮助业务快速重构的特性,将会在IOT领域迎来巨大发展潜力,甚至有可能会比它在云端的潜力更大。本文将致力于构建一个利用Rancher&RancherOS来管理运行在树莓派上的容器集群。

目前业界主流基本都是在x86架构上使用Docker,除了因为Intel在服务器领域的绝对领导地位之外,x86 CPU的确在性能上有着卓越的表现。但是近些年来,随着云计算的迅猛发展,引来了数据中心的大规模建设,慢慢地大家对数据中心PUE尤其是CPU功耗有了更高的要求。ARM CPU虽然性能不如x86,但是在功耗上绝对有着无法比拟的优势,同时我们知道并不是所有的服务都有高性能的CPU需要。很多厂商在都对ARM服务器投入了研发资源,但是效果上目前来看并不是太好,ARM处理器在服务器领域并没有如在移动端那样被快速接受,主要是因为市场接受度及服务器市场的性能要求所致。


但是在物联网(IOT)领域,ARM处理器却是霸主级的地位,毕竟在这个领域功耗胜过一切。那么我们可以想象,未来会占大市场的IOT设备中,会出现各种尺寸各种架构,内置操作系统也不统一,没有通用程序打包标准,几乎每种设备程序的开发框架均不同,IOT设备中程序部署升级回滚等操作不够灵活,等等这样那样的问题。

而这些问题,我们可以借鉴X86时代的经验,用Docker容器来解决它们。Docker能降低IOT应用管理的负载度,但是在物理设备和Docker之间,我们还需要一个轻量级的操作系统。这个OS需要是完全可以定制的,可以针对不同设备需求,裁剪或增加对应的程序模块,更小体积更少进程意味着更低的功耗。

根据以上判断和需求,我经过了一番探索,最终选择了RancherOS。它本身的特性是:

  • 真正容器化的Linux操作系统极致精简,所有服务(包括系统服务)均运行在容器中,可以以容器方式对其进行任意定制
  • 内置了Docker Engine,无需在安装系统后再进行Docker安装
  • 完全开源 https://github.com/rancher/os ,我们可以进行各种深度定制
  • 最最重要的,支持ARM

在RancherOS的整体架构中,最底层毋庸置疑是Linux kernel,系统启动后的PID 1用system-docker代替,由它来把udev、dhcp、console等系统服务启动,同时会启动user-docker,用户运行的应用程序均跑在user-docker下。


我们以树莓派为例,将RancherOS部署在其之上。这里需要提示的是,RancherOS每个版本release之时,都会放出树莓派的支持版本,比如本次分享使用的v0.7.0版本https://github.com/rancher/os/releases/download/v0.7.0/rancheros-raspberry-pi.zip。通过dd命令将RancherOS写到树莓派的SD卡上,通电点亮树莓派。


查看PID 1是system-docker:


通过system-docker ps 查看启动的系统服务:


正常来说,我们都得设置一下docker registry mirror,这样方便pull镜像。RancherOS的配置,都是通过ros config命令来配置,比如设置user-docker的mirror:

$ sudo ros config set rancher.docker.extra_args [--registry-mirror,https://xxxxxxx]
$ sudo system-docker restart docker # 重启user-docker

最终,可以看到:


RancherOS有一个我认为比较好的特性,就是支持很方便的对Docker Engine版本进行切换。目前Docker迭代的速度并不慢,实际上很多程序不一定会兼容比较新的Engine,Docker Engine版本的管理变得越来越重要。尤其是在测试环境中,我们有时确实需要变换Docker Engine版本,来构建测试场景:

$ sudo ros engine list  #查看当前版本支持的engine有哪些
disabled docker-1.10.3
disabled docker-1.11.2
current  docker-1.12.1
$ sudo ros engine switch docker-1.11.2 #切换docker-1.11版本

此外,如果对Docker Engine有更特殊的需求,还可以定制自己的版本,然后让system-docker来加载它。

只需将编译好的Docker Engine放到Scratch镜像中即可:


这部分可以参考:https://github.com/rancher/os-engines

另外,如果习惯了使用相应Linux发行版的命令行,那么也可以加载对应的Console镜像(当然如果考虑精简系统也可不必加载):


此部分需要进行深度定制,可以参考:https://github.com/rancher/os-images


RancherOS更多酷炫的功能,可以访问官方的文档:http://docs.rancher.com/os

RancherOS介绍完毕后,我们可以在单机树莓派上做容器管理了,喜欢命令行的当然最好,喜欢UI管理的,推荐两款可以在树莓派上运行的管理程序。

portainer https://github.com/portainer/portainer ,其有专门的arm镜像 portainer/portainer:arm ,运行后:

$ docker run --restart=always -d -p 9000:9000 --privileged -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer:arm


更加简约的 ui-for-docker https://github.com/kevana/ui-for-docker ,运行如下:

$ docker run --restart=always -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock hypriot/rpi-dockerui


单机树莓派之后,我们就要考虑如何将多个树莓派组成Docker集群。一提到Docker集群,我们就会考虑需要编排引擎的支持,无非就是主流的Mesos、Kubernetes、Swarm,还有非主流的Cattle、Nomad之流。那么在IOT场景下,我们最需要考虑的就是精简,所以我选择了新版的Swarm。将RancherOS的Engine切换到1.12.3,然后构建Swarm集群。

简单得执行swarm init和join后,我们就得到了一个树莓派Docker集群:


然后我们可以快速执行一个小demo:

swarmkit demo
$ docker service create --replicas 1 -p 80 --name app armhf/httpd
$ docker service scale app=2
$ docker service ps app


更多ARM相关的Docker镜像,可以到这两个地方查找:

  • https://hub.docker.com/r/armhf
  • https://hub.docker.com/u/aarch64

RancherOS设计之初是为了构建一个运行Rancher的轻量级操作系统,那么Rancher本身在ARM的支持上也在不断推进中,相应的PR也有提交:https://github.com/rancher/rancher/pull/4704 。不过目前来看,对rancher-server的ARM化还是比较麻烦,对agent的节点支持ARM相对简单一些,也就是说rancher-server仍然运行在x86架构上,而Agent节点可以支持ARM和x86。

Kubernetes的ARM支持在社区中也有很多人在做,比如:https://github.com/luxas/kubernetes-on-arm ,来自社区的分享:


秀一下,我的“家庭树莓派数据中心”:


最后,我要特别感谢RancherOS的开发者们,他们帮助我解决了很多问题;另外还要特别感谢MBH树莓派社区的伙伴,提供了硬件设备,支持我的技术探索,并提供了很多帮助。

Q&A

Q:先问一个问题,您家里的树莓集群用来做什么?有哪些场景会用到树莓Docker?

A:这个需求点来自 MBH树莓派社区的朋友,他们提出希望能够简化多个树莓派上部署程序,同时我对未来Docker在arm服务器上的运行抱有很大期望,我只是对这块进行了一些探索。目前还没有找到真实的需求点,还需要更深入的落地。

Q:您对CoreOS和RancherOS的区别或优劣势上,您是怎么看的?多谢!

A:实际上使用了CoreOS和RancherOS后,会发现这两个在思路和理念上确实很像。RancherOS比CoreOS的容器化做的更加深入,CoreOS的稳定性会更好。RancherOS设计面向Rancher,CoreOS更多会考虑Kubernetes。CoreOS应该会持续深耕服务器端,而RancherOS也许会在IOT端发力一下。

Q:树莓派的内存不大,单个主机上容器数会有很大限制吧?

A:树莓派上跑是为了只是为了单纯简化程序部署,当然不会追求计算密度。计算密度那是服务器关注的事,另外,树莓派的内存不大只是暂时的。

Q:请问在arm架构里partition是怎么做的?

A:dd写完镜像后,默认又一个根分区,可以再建一个分区,把docker的目录挂上去,这样能充分利用整个sd卡。

Q:RancherOS上使用Docker,应用能在容器中通过GPU执行浮点运算吗?需要装驱动吗?在哪装?

A: RancherOS是一个完全可以定制的操作系统。只要有对应的module,都可以初始化到RancherOS中。

树莓派从U盘启动系统

用U盘来代替SD卡安装Raspbian的好处就是,U盘比SD卡更加耐用。不要再担心SD卡不经用的问题。
准备SD卡8g,准备U盘32G(实际上SD卡64M以上即可),U盘4G以上即可
1、直接写img进U盘
(关于U盘或SD卡写镜像参考SD卡镜像写入教程)
下图是SD卡和已经写入img的U盘(所有涉及软件详见附件)
U盘boot分区文件列表:
2、下载HPUSBFW(HPUSBBoot)U盘格式化工具
下载MS-Dos文件
3、格式化SD卡写入dos文件
写入后SD卡文件展示
4、修改U盘boot分区文件cmdline.txt
修改root=/dev/mmcblk0p2root=/dev/sda2保存
改前:
改后:
5、把所有文件ctrl+A全选,复制到SD卡里
SD文件列表:
2017年新版的rpi系统需要在boot下面创建ssh文件来默认开启SSH
6、ssh登录树莓派,开机测试
小米路由器设备查看:

 

将 Raspberry Pi 联机模拟器连接到 Azure IoT 中心 (Node.js)

本教程会先介绍使用 Raspberry Pi 联机模拟器的基础知识。 然后介绍如何使用 Azure IoT 中心将 Pi 模拟器无缝连接到云。

如果有物理设备,请访问将 Raspberry Pi 连接到 Azure IoT 中心以开始进行操作。

Connect Raspberry Pi web simulator to Azure IoT Hub
Start Raspberry Pi simulator

准备工作

  • 了解 Raspberry Pi 联机模拟器的基础知识。
  • 创建 IoT 中心。
  • 在 IoT 中心内为 Pi 注册设备。
  • 在 Pi 上运行示例应用程序,将模拟传感器数据发送到 IoT 中心。

将模拟 Raspberry Pi 连接到创建的 IoT 中心。 然后,使用模拟器运行示例应用程序,生成传感器数据。 最后,将传感器数据发送到 IoT 中心。

学习内容

  • 如何创建 Azure IoT 中心以及如何获取新的设备连接字符串。 若没有 Azure 帐户,只需几分钟即可创建免费的 Azure 试用帐户
  • 如何使用 Raspberry Pi 联机模拟器。
  • 如何将传感器数据发送到 IoT 中心。

Raspberry Pi Web 模拟器概述

单击用于启动 Raspberry Pi 联机模拟器的按钮。

Web 模拟器中有三个区域。

  1. 程序集区域 – 默认电路是 Pi 连接到 BME280 传感器和 LED。 该区域在预览版本中为锁定状态,因此目前无法执行自定义操作。
  2. 编码区域 – 一个联机代码编辑器,可在其中使用 Raspberry Pi 进行编码。 默认示例应用程序可帮助从 BME280 传感器收集传感器数据,并将其发送到 Azure IoT 中心。 该应用程序与真实 Pi 设备完全兼容。
  3. 集成控制台窗口 – 显示代码输出。 在此窗口的顶部,有三个按钮。
    • 运行 – 在编码区域运行应用程序。
    • 重置 – 将编码区域重置为默认示例应用程序。
    • 折叠/展开 – 可使用右侧的按钮折叠/展开控制台窗口。
备注

目前 Raspberry Pi Web 模拟器在预览版中可用。 请通过 Gitter Chatroom 向我们提供意见和建议。 源代码在 Github 上是公开的。

Pi 联机模拟器概述

创建 IoT 中心

  1. Azure 门户中,依次单击“新建” > “物联网” > “IoT 中心”。在 Azure 门户中创建 IoT 中心
  2. 在“IoT 中心”窗格中,输入 IoT 中心的以下信息:名称:输入 IoT 中心的名称。 如果输入的名称有效,会显示一个绿色复选标记。定价和缩放层:选择“F1 – 免费”层。 此选项对于本演示来说已足够。 有关详细信息,请参阅定价和缩放层资源组:创建用于托管 IoT 中心的资源组,或使用现有的资源组。 有关详细信息,请参阅使用资源组管理 Azure 资源位置:选择与创建的 IoT 中心最靠近的位置。固定仪表板:选中此选项可以方便地从仪表板访问 IoT 中心。

    输入创建 IoT 中心所需的信息

    重要

    IoT 中心将公开为 DNS 终结点,因此,命名时请务必避免包含任何敏感信息。

  3. 单击“创建” 。 创建 IoT 中心可能需要数分钟的时间。 可在“通知”窗格中查看进度。请查看 IoT 中心的进度通知
  4. 创建 IoT 中心后,请在仪表板中单击它。 记下“主机名”,并单击“共享访问策略”。获取 IoT 中心的主机名
  5. 在“共享访问策略”窗格中单击“iothubowner”策略,复制并记下 IoT 中心的连接字符串。 有关详细信息,请参阅控制对 IoT 中心的访问
备注

此设置教程不需要此 iothubowner 连接字符串。 不过,在完成此设置以后,可能需要将其用于某些讲述其他 IoT 方案的教程。

获取 IoT 中心连接字符串

在 IoT 中心为设备进行设备注册

  1. Azure 门户中打开 IoT 中心。
  2. 单击“设备资源管理器”。
  3. 在“设备资源管理器”窗格中,单击“添加”将设备添加到 IoT 中心。 然后执行以下操作:设备 ID:输入新设备的 ID。 设备 ID 区分大小写。身份验证类型:选择“对称密钥”。自动生成密钥:选中此复选框。将设备连接到 IoT 中心:单击“启用”。在 IoT 中心的设备资源管理器中添加设备
    重要

    收集的日志中可能会显示设备 ID 用于客户支持和故障排除,因此,在为日志命名时,请务必避免包含任何敏感信息。

  4. 单击“保存” 。
  5. 创建设备后,在“设备资源管理器”窗格中打开设备。
  6. 记下连接字符串的主密钥。获取设备连接字符串

在 Pi Web 模拟器上运行示例应用程序

  1. 在编码区域,请确保使用的是默认示例应用程序。 将第 15 行的占位符替换为 Azure IoT 中心设备连接字符串。 替换设备连接字符串
  2. 单击“运行”或键入 npm start 以运行应用程序。

应看到以下输出,该输出显示传感器数据和发送到 IoT 中心的消息输出 - 从 Raspberry Pi 发送到 IoT 中心的传感器数据

后续步骤

此时已运行示例应用程序,以收集传感器数据并将其发送到 IoT 中心。

wordpress安装主题或插件需要FTP问题彻底解决

很多小伙伴在使用Wordpress的时候,都会出现安装主题或插件需要FTP的情况,有些朋友填入以后,结果还是无法下载和安装。其实这个问题解决起来要注意几个问题:

彻底解决wordpress安装主题或插件需要FTP问题

方法/步骤

  1. 使用FTP软件连接FTP空间,进入wp-content目录,新建tmp文件夹,设置文件夹的权限为777

  2. 下载:在FTP中返回网站根目录,找到wp-config.php这个PHP文件,下载到本地

  3. 修改:在wp-config.php中添加下列三行代码:

    【使用记事本编辑器,推荐使用:Notepad++】

    define(‘WP_TEMP_DIR’, ABSPATH.’wp-content/tmp’);/* WordPress的临时目录。*/

    define(“FS_METHOD”, “direct”);

    define(“FS_CHMOD_DIR”, 0777);

    define(“FS_CHMOD_FILE”, 0777);

    注意:要在定义ABSPATH的后面,即在它的后面添加

    if ( !defined(‘ABSPATH’) )

    define(‘ABSPATH’, dirname(__FILE__) . ‘/’);

    ================================

    最后的代码应该是:

    if ( !defined(‘ABSPATH’) )

    define(‘ABSPATH’, dirname(__FILE__) . ‘/’);

    define(‘WP_TEMP_DIR’, ABSPATH.’wp-content/tmp’);

    define(“FS_METHOD”, “direct”);

    define(“FS_CHMOD_DIR”, 0777);

    define(“FS_CHMOD_FILE”, 0777);

    彻底解决wordpress安装主题或插件需要FTP问题
  4. 上传:上传覆盖wp-config.php文件

  5. 设置wp-content目录中的plugins(插件)和themes(主题)文件夹权限为777。

    至此,你的插件和主题已经可以自动更新了。

    此为终极解决办法,其它都为阉割版本。

    为了安全,应在.htaccess中把 tmp、themes、plugin 这些读写权限为777的文件夹,设置为没有执行权限。

  6. 看一下成功效果

    彻底解决wordpress安装主题或插件需要FTP问题