標籤:Docker

結合docker swarm 建置ElasticSearch Cluster

結合docker swarm 建置ElasticSearch Cluster

最近因為有要整合ELK方案的需求,因此又再度接觸了這個曾經相當熟悉的工具,還記得那個時候(也才1年多前),還是在2.x版左右,kibana的介面還是長這個樣子的時候。

在先前的公司,有平台團隊專門架設這個服務提供RD團隊整合使用,對於使用是絲毫不陌生,但是建置卻完全沒有經驗。沒想到現在已經轉眼間來到了6.1版本,介面跟架構看起來調整的更鮮艷與簡潔(?),我知道ELK目前在windows上面仍然是有一鍵安裝的版本。對於開發要測試的需求上已經相當足夠(連結),但因為我們目前對外主機主要都是CentOS,因此我這次預計實作如下:

假設我有2台CentOS主機的情境下(一台稱為A Host, 一台稱作B Host),如何透過各別安裝elasticsearch的docker 容器,來串連成elasticsearch 的集群。

同一台的多個容器理論上是相對簡單的,而這邊會遇到的問題,主要的關鍵就是如何解決跨主機間docker容器的通信問題,網路架構也通常都是應用程式間管控較為複雜的一個部分

 

這邊我打算採用Docker Swarm,Swarm為Docker自行開發的容器調度工具,其中的跨主機建立overlay網路功能看起來是非常符合我的情境需求,由於是Docker平台內建工具,看起來並不需要額外的安裝與學習,因此我先從這套工具開始著手,至於關於其他容器調度工具還包含了,Kubernetes、Mesos等。甚至現在的顯學看起來是Kubernetes(k8s),有許多的討論也直指要如何決定該採用哪種方案。

目前看到這一篇(連結)是相對從各面向都有討論到,有興趣的可以看看

Docker swarm的架構圖(來自Docker官網)

從docker 1.9版開始,DockerSwarm已經是內建工具,因此透過以下指令,就可以將主機宣告成DockerSwarm的Manager主機(第一台總是master嘛)

sudo docker swarm init

若有成功啟動DockerSwarm的話,會提示以下訊息

docker swarm join –token SWMTKN-1-5wsc3yya3e87w2e84jkzbpieubpxr9v6qwnbj87m6t2ynv7kxm-8q5amih216368atw8adklx24f %A Host IP%:2377
這個hint很明顯就是我們可以在其他的Host(稱作Worker),透過以上指令來加入到Manager下的叢集中。同時他是透過A Host的2377 Port來進行串連
但假如希望建立起來的Swarm使用其他Port的話,我們可以使用以下指令來做
docker swarm init –advertise-addr=%A Host IP% –listen-addr %A Host IP%:2377
所以我們也可以使用這句語法檢查,是否有啟動了這兩個Port

sudo netstat -nap | grep ^tcp.*dockerd

正常應該會列出對應的2377與7946

tcp6 0 0 :::7946 :::* LISTEN 28184/dockerd
tcp6 0 0 :::2377 :::* LISTEN 28184/dockerd

接著我們在B Host上,輸入剛剛建立完swarm manager 所提示的加入語法

   docker swarm join –token SWMTKN-1-5wsc3yya3e87w2e84jkzbpieubpxr9v6qwnbj87m6t2ynv7kxm-8q5amih216368atw8adklx24f %A Host IP%:2377

在這邊若有無法加入的情況的話,可以往防火牆先檢查,若是防火牆確定有通(telnet看看),那我這邊有遇到原本怎樣都加入不了,但是重開機、重啟docker後,就可以加入的情況。

若Worker成功加入Swarm的話,我們可以在A Host輸入以下指令確認是否節點都完整

docker node ls

既然A-B Host已經加入了同一個網路架構,接著就是建立覆疊網路

sudo docker network create   –driver overlay  –attachable es_net
註:這邊–attachable 若後續要透過run 語法加入指定網路的話,參數一定要加,是不是Docker Compose就不用加,我不確定
成功建立overlay網路後,我們就可以透過以下指令看到我們的網路已經被建立起來,SCOPE是顯示swarm , Driver是顯示overlay
sudo docker network ls
現在網路架構已經看似完成,接著我們來準備Elasticsearh的服務配置吧
這邊我寫了一個腳本來自動建立elasticsearch的相關目錄,目前只要elasticsearch會異動到的檔案目錄權限要開啟來,否則之後容器啟動後,會有權限例外產生:
腳本中改777的部分都是因為遇到所以加上去的,可以自行改成合適的權限配置。
sudo cd /mnt
sudo mkdir elasticsearch
cd elasticsearch
sudo git init
sudo git remote add origin "http://git server ip/scm/mes/elasticsearch.git"
sudo git pull origin master
sudo mkdir config/scripts
sudo mkdir esdatadir
cd esdatadir
sudo mkdir log
sudo mkdir data
sudo chmod 777 /mnt/elasticsearch/esdatadir/*
sudo chmod 777 /mnt/elasticsearch/config/scripts

cd /mnt/elasticsearch

config下的檔案,因為A, B Host各自擁有自己的獨立硬碟,因此我假設他們的環境配置應該都一致,jvm.options、log4j2.properties、檔案都一樣,只有Elasticsearch的yml檔會有些許差異:

path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
cluster.name: meso_es_cluster1
node.master: true #if worker then mark it
node.name: ${HOSTNAME}
network.host: 0.0.0.0
discovery.zen.ping.unicast.hosts: ["A HOST IP", "B HOST IP"]
以上都完成以後,就是來啟動Docker 容器的時候了,以A Host為例,啟動語法如下,B Host只是改–name成es2
sudo docker run -d -v /mnt/elasticsearch/esdatadir/data:/var/lib/elasticsearch -v /mnt/elasticsearch/esdatadir/log:/var/log/elasticsearch -v /mnt/elasticsearch/config:/usr/share/elasticsearch/config -p 9200:9200 -p 9300:9300 --net=es_net --name es1 --security-opt seccomp=unconfined -e "bootstrap.memory_lock=true" -e ES_JAVA_OPTS="-Xms1g -Xmx1g" --ulimit memlock=-1:-1 elasticsearch:5.6.6

分別執行後,我們可以看到docker ps 下是否狀態是正常在up的。

補充說明,啟動es容器時,我曾經發現會有以下的錯誤訊息:max virtual memory areas vm.max_map_count [65530] is too low(請透過docker logs查看)
這個問題若資源分配問題的話,可以透過以下指令解決:
sudo sysctl -w vm.max_map_count=262144
 但我也有一個疑問,logs是記錄容器內部的jvm的錯誤,但是我是在容器外部下語法可解決,這個原因我確實不清楚就是了..

若都是正常,我們可以透過elasticsearch的Api來檢查我們的es cluster是否有正常運作起來

從瀏覽器輸入A Host IP:9200,會返回相關json資訊,若是如下,我們可以認定cluster有啟動,而且服務版本正確,

可以看到name的部分,就正是各別主機上Docker 容器的name,而cluster_name因為配置所以會一致、而若有正確加入的話,cluster_uuid必須要一致
註:我在實作的時候,就一直遇到B Host啟動的起來,但是他無法加入cluster,所以cluster_uuid一直顯示為_na_,後來竟然是整個docker服務重啟就好了,這個羅生門,讓我相信3R的救命招(Recycle, Reset, Reboot),測試期間,也可以透過docker exec -it B HOST Container IP ping -c 3 A_Host_IP來看看是否可以透過容器內解析出跨主機的另一個同網路下的容器名稱

 

如何觀察Elasticsearch的Cluster狀態呢?具瞭解在es 2.x版本的時候,有一套es的plugin,叫作kopf,是拿來可以直接透過es api來監控es服務的工具

後來5.x版以後,發現plugin功能被拔掉了,取而代之是獨立的”cerebro“套件可以達成完全一樣的功能,看來是同個作者寫的。

介面如下

只要在Node Address輸入A Host es容器名稱:9200(注意容器互連必須透過容器名稱,而不能只是ip),就可以看到以下的dashboard,相當的方便,除了可以即時監控Node的資源使用狀況,也可以看到目前的index數量與使用狀況、空間

cerebro 這邊,只需要透過以下指令,就可以啟動:

sudo docker run -d -p 9000:9000 –name cerebro –net es_net yannart/cerebro:latest

同場加映Kibana 5.6.6的啟動指令

sudo docker run –name meso-kibana –link es1:elasticsearch –net es_net -p 5601:5601 -d kibana:5.6.6
透過A Host IP:5601啟用Kibana後,就可加入已經自定好的Index pattern來使用囉
將你的Nodejs React Web App Docker化

將你的Nodejs React Web App Docker化

假設目前已選用React的框架,我試驗的這套名叫https://github.com/zuiidea/antd-admin

方案目錄結構如下:

主要react程式都放在src的目錄下

node_modules是在npm install的時候,才會把相依套件安裝在這個目錄裡面

以下步驟的目的主要是希望啟動一個node.js 的web server,將我們的react web啟動後,可以透過外部編修程式來除錯與開發

production環境,不需要另外開放目錄了,而且依正常nodejs 的production build,就也編譯好了,所以不會因為src的code異動而影響!

 

 

1.在webapp的根目錄,建立DockerFile (touch Dockerfile)

# You should always specify a full version here to ensure all of your developers
# are running the same version of Node.
FROM node:7.8.0

# Override the base log level (info).
ENV NPM_CONFIG_LOGLEVEL warn

# Install and configure `serve`.
RUN npm install -g serve
CMD serve -s build
EXPOSE 8000

# Install all dependencies of the current project.
COPY package.json /node-app/package.json
#COPY npm-shrinkwrap.json npm-shrinkwrap.json
# The -g switch installs the Express Generator globally on your machine so you can run it from anywhere.
RUN cd /node-app;npm install

# Copy all local files into the image.
COPY . /node-app

# Build for production. 正式機時,要解除註解重建images,不然會大大影響效能
# RUN cd /node-app; npm run build

2. 建立Docker Images

docker build -t react-test-docker .

3. 啟動Docker Container(註,因為沒有標記production build,所以要指定start的路徑,start後,要加上prefix參數,指定你的web app目錄)
sudo docker run -d \
            -v /mnt/nodejs-app/mesodashboard/antd-admin-dashboard/src:/node-app/src \
            -p 8000:8000 \
            –name react-test-server \
            react-test-docker \
            npm start --prefix /node-app
[Docker] docker-compose定義檔範例

[Docker] docker-compose定義檔範例

當平台漸漸成形,對於外部套件、方案相依性定調以後,每次都要手動建置測試運行環境,即使docker已經把建置動作簡化到一行指令了,但是還是令人覺得瑣碎。

這個時候,docker-compose這個解決方案,大幅的簡化了我們的部署工作:傳送門

它僅需要配置服務定義檔(yml檔名),就可以跟現有的docker images整合,立即建置出所需的架構環境!

version: '2.1'

services:
  memcache:
    image: memcached
    ports:
      - "11211:11211"
    command: memcached -m 1024m

  hadoop:
    image: "sequenceiq/hadoop-docker:2.7.0"
    ports:
     - "8030:8030"
     - "8040:8040"
     - "8042:8042"
     - "8088:8042"
     - "19888:19888"
     - "49707:49707"
     - "50010:50010"
     - "50020:50020"
     - "50070:50070"
     - "5007:5007"
    command: /etc/bootstrap.sh -d

  cassandra:
    image: "cassandra"
    ports:
     - "9042:9042"
    volumes:
     - /mnt/cassandra/data:/var/lib/cassandra
 
  mariadb:
    image: mariadb
    ports:
     - "3306:3306"
    volumes:
     - /mnt/mariadb/data:/var/lib/mysql
     - /mnt/mariadb/config:/etc/mysql/conf.d
    restart: always
    environment:
       MYSQL_ROOT_PASSWORD: 525402040966518776
       MYSQL_USER: ap_user
       MYSQL_PASSWORD: jUqJ75aFbJEU
  
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    links:
      - mariadb
    environment:
      PMA_HOST: mariadb
      PMA_PORT: 3306
    ports:
     - "8088:80"

  my-python-app:
    depends_on:
     - mariadb
     - cassandra
     - hadoop
     - memcache
    image: python35-app
    volumes:
     - /mnt/python-app/src:/usr/src/app
    ports:
     - "12345:12345"
    command: /usr/src/app/run.sh

註:

1.首先是version,據我所知,目前大部分幾個月前安裝的docker,至少可以支持到2.1,但不見得能支持到3.0的版本。相關upgrade的議題,必須持續survey

2.不需要export的port就不要開,可以透過link或是建立network來進行容器互連

3.可以善用command、environment、volumn等docker支持的掛載與注入的方式來配置容器

4.可以透過現成已build好的image或是動態透過build dockerfile來定義服務。這一段上述例子沒有,有需要時再查使用方式

 

最後,啟動服務群指令(記得加-d,否則會被lock在shell,被script轟炸):

sudo docker-compose up -d

若要下架也很簡單(其他還有run、stop等指令可用)

sudo docker-compose down

 

ELK Stack安裝的眉眉角角-Part3:FileBeat

ELK Stack安裝的眉眉角角-Part3:FileBeat

上一篇尾聲記得我還提到,當時沒有使用FileBeat的原因是因為還沒架起來

結果今天重新從 getting started with filebeat的官網文件(傳送門)重新照表操課了一次

結果意外地就架起來了(所以讀官網文件是何等重要的一件事),雖然成果相當的陽春,但是也很足夠記錄下來

首先-設定檔,僅保留最簡單且最必要的部分

我如往常的在mnt下建立了filebeat的目錄,並加入了/mnt/filebeat/filebeat.yml檔案,內容如下

filebeat.prospectors:
- type: log
  enabled: true
  paths:
    - /var/log/mesocollection/*/*.log
  
  reload.enabled: true
  reload.period: 30s

#-------------------------- Elasticsearch output ------------------------------
output.elasticsearch:
  hosts: ["elasticsearch:9200"]
  template.enabled: false
  index: "meso_sys_localfile_fb"

註:這邊path因為上一篇google 到可以用*追蹤動態目錄(例如以日期、小時分類目錄)的情況,filebeat一樣可以支持,另外關於elasticsearch的index,我們一併在這邊設定好,後續可以透過es的api來檢查寫入的狀況。關於輸入elasticsearch,我們這次與logstash的file寫入少了定義filelds parsing的流程,這一段目前查詢起來,除了general像是apache、mysql等大應用的log格式(所以可以參考他們的log格式,可以省點事),否則可能必須透過filebeat轉接logstash再透過fileter parsing後,才能寫入自定義的fields到elasticsearch的index中。(待查證)

接著key入以下指令,我們就可以把filebeat的image run起來:

docker run -d --link elasticsearch-test:elasticsearch -v /mnt/filebeat/filebeat.yml:/filebeat.yml -v /mnt/python-app/mesocollection/logs:/var/log/mesocollection prima/filebeat:5

接著我們可以觸發一下記錄log的行為,例如call api,我們輸入docker logs的指令追蹤一下看看:

2017/07/31 02:57:30.841300 log.go:116: INFO File is inactive: /var/log/mesocollection/20170731/grpc_server_10.log. Closing because close_inactive of 5m0s reached.
2017/07/31 02:57:30.841296 log.go:116: INFO File is inactive: /var/log/mesocollection/20170731/RepositorySettingsHelper_10.log. Closing because close_inactive of 5m0s reached.
2017/07/31 02:57:32.836147 log.go:116: INFO File is inactive: /var/log/mesocollection/20170731/MC_Entry_10.log. Closing because close_inactive of 5m0s reached.
2017/07/31 02:57:32.836248 log.go:116: INFO File is inactive: /var/log/mesocollection/20170731/MC_MainService_10.log. Closing because close_inactive of 5m0s reached.
2017/07/31 02:57:32.836211 log.go:116: INFO File is inactive: /var/log/mesocollection/20170731/MC_Return_10.log. Closing because close_inactive of 5m0s reached.
2017/07/31 02:57:45.646417 metrics.go:39: INFO Non-zero metrics in the last 30s: filebeat.harvester.closed=5 filebeat.harvester.open_files=-5 filebeat.harvester.running=-5 publish.events=5 registrar.states.update=5 registrar.writes=1

若出現以上的logs,代表filebeat有偵測到檔案的變動。

接著我們一樣透過$ curl -XPOST http://yourhost:9200/meso_sys_filelog_fb/_search?pretty=true來看看es寫入的狀況

{
  "took" : 8,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 41,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "meso_sys_localfile_fb",
        "_type" : "log",
        "_id" : "AV2WiYNRVf3DdKZYkE65",
        "_score" : 1.0,
        "_source" : {
          "@timestamp" : "2017-07-31T02:46:15.762Z",
          "beat" : {
            "hostname" : "6c8d38b686db",
            "name" : "6c8d38b686db",
            "version" : "5.3.0"
          },
          "input_type" : "log",
          "message" : "2017-07-31 10:46:11,021 - MC_MainService - INFO - entry log : behavior:update_system_user_rdb, data={\"$data$\": \"{\\\"firstName\\\": \\\"I-Ping\\\", \\\"email\\\": \\\"paul@meso-tek.com\\\", \\\"lastName\\\": \\\"Huang\\\"}\", \"$query$\": \"{\\\"id\\\": \\\"0e5564e8-1ac7-45db-9d0b-6f79643ca857-1501469142.056618\\\", \\\"account\\\": \\\"paul\\\"}\"}, files_count=0",
******************************************************略

若有以上的json記錄,那代表elasticsearch也可以正常的寫入了

大部分到此,kibana也不太有什麼問題了。

但問題仍是,因為log message沒有被拆解,所以我們只能把每一行當成是log message欄位來搜尋,對於報表並沒有直接幫助。

因此關於設定log message的機制,究竟只能透過logstash轉接,還是有filebeat的plugin可以用呢?這個列為本週任務來研究看看吧~

以上先記錄了filebeat最簡單的啟用與串接方式囉

 

參考:

FileBeat getting started:https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-getting-started.html

How Filebeat works:https://www.elastic.co/guide/en/beats/filebeat/current/how-filebeat-works.html

 

Docker的Hadoop一鍵啟動之旅

Docker的Hadoop一鍵啟動之旅

大數據、雲端運算這麼夯,數據資料的基礎建設是何等的重要,Hadoop基本上是個分佈式的開源應用程式框架(任意門),除了提供經典的MapReduce的平台,另外還支援分佈式的檔案系統,會說它是經典是因為現在的實務的應用程式已經都轉移到Apache Spark去了,這邊就暫且不提。

 

一般hadoop要有成效,至少要有4台主機以上….因此要建置Hadoop Distributed File System,最簡單的方式,還是透過Docker了

DockerHub上就有公司很友善的提供了Image來讓我們可以建置(試用)Hadoop(支援到Hadoop 2.7版本) …傳送門

看過Hadoop安裝於Linux的許多教學後(從java安裝到node設定,會有點想死),會萬千感謝提供這個Images的善心人士整個弄到可以一鍵安裝

 

廢話不多說,Hadoop Image Docker啟動命令:

sudo docker run -d --name=hadoop-dev-server \
	-p 8020:8020 \
	-p 8030:8030 \
	-p 8040:8040 \
	-p 8042:8042 \
	-p 8088:8088 \
	-p 19888:19888 \
	-p 49707:49707 \
	-p 50010:50010 \
	-p 50020:50020 \
	-p 50070:50070 \
	-p 50075:50075 \
	-p 50090:50090 \
	-p 9000:9000 \
	762e8eefc162 /etc/bootstrap.sh -d

建立好以後我們列表出來所有的container,發現,他已經好好的在運行了。

c93953e56bb6 762e8eefc162 “/etc/bootstrap.sh -d” 9 hours ago Up 9 hours 0.0.0.0:8020->8020/tcp, 2122/tcp, 0.0.0.0:8030->8030/tcp, 0.0.0.0:8040->8040/tcp, 0.0.0.0:8042->8042/tcp, 0.0.0.0:8088->8088/tcp, 0.0.0.0:9000->9000/tcp, 0.0.0.0:19888->19888/tcp, 0.0.0.0:49707->49707/tcp, 0.0.0.0:50010->50010/tcp, 0.0.0.0:50020->50020/tcp, 0.0.0.0:50070->50070/tcp, 0.0.0.0:50075->50075/tcp, 8031-8033/tcp, 0.0.0.0:50090->50090/tcp hadoop-dev-server

註:這個image可以讓我們一鍵啟動Single Node來試著與他的介面試著交互,然而若要實作多node的hadoop,來建立真正的分散式服務,怎麼辦?

一樣透過docker啊,多好,又有人建立了dockerfile(傳送門again),這邊先不談,先把基礎環境建立與操作方法做一篇記錄:

 

這裡面有好多port都bind出來了,但僅介紹一些常用Port,有部分Port估計是分散式架構下在用的,首先是50070,這個是Web介面,除了可以看到Hadoop Service的運行狀態,空間使用狀況,還可以看到檔案目錄清單

接著是9000,預設HDFS協定的Port,等等我們立馬來使用看看

Hadoop的檔案系統的使用方式,我知道有2種(有沒有其他方式,待後續一探究竟)

一種就是透過Web的方式,Python裡面可以安裝WebHDFS套件,透過http://xxxxx:50070,實際上是透過Restful Api進行檔案傳輸

而另一個就是直接透過hdfs協定,然而,要透過HDFS協定,就要先安裝Hadoop的程式,官網

(注意版本…目前Hadoop 2.7版本,請下載盡量相近的Hadoop版本,我就有遇到用太舊的hadoop程式去連2.7版的,出現的錯誤訊息是IPC version 9 cannot communicate with client version 4,追查了一下發現只是版本太舊的問題,透過以下下載安裝方式,就可以解決了)

這一塊因為必須具備Hdfs 的driver,所以必須要有相關的環境,像我在windows 上跑的python就因為driver問題,而選擇透過webhfds來交互

 

這次我下載的是hadoop-2.6.5 binary的版本(我之前去下載一些舊版本的hdfsclient的程式,就有遇到過不相容的狀況)

#wget http://apache.stu.edu.tw/hadoop/common/hadoop-2.6.5/hadoop-2.6.5.tar.gz

#tar -xzcf hadoop-2.6.5.tar.gz

經過一連串解壓以後,我們多了一個Hadoop 2.6.5的目錄,然而,Hadoop的程式是透過Java 寫的,所以要運行起來的話,Java 環境也是必要安裝

一種是透過手動的方式配置,詳細記錄如下:

tar -zxvf /home/paul/download/jdk-8u144-linux-x64.tar.gz -C /usr/local
mv /usr/loca/jdk-8u144-linux-x64.tar.gz /usr/local/jdk
sudo /etc/profile.d/development.sh

# 加入以下內容
JAVA_HOME=/usr/local/jdk
CLASSPATH=.:$JAVA_HOME/lib
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME CLASSPATH PATH

# 立即生效
. /etc/profile
ln -s -f /usr/local/jdk/bin/java /usr/bin/java
ln -s -f /usr/local/jdk/bin/javac /usr/bin/javac

# 關閉selinux
sudo nano /etc/selinux/config
# 將SELINUX=enforcing改為SELINUX=disable
# 查看java版本
java -version

另一種就是透過centos的方式安裝

#sudo yum install java

#java -version

印出以下代表運行java 該有的環境已經有了

openjdk version “1.8.0_141”
OpenJDK Runtime Environment (build 1.8.0_141-b16)
OpenJDK 64-Bit Server VM (build 25.141-b16, mixed mode)

然後,我們立即對我們的容器進行hdfs連結

#cd ~/hadoop-2.6.5/bin

#./hdfs dfs -ls hdfs://localhost:9000/

註:若透過後者easy_install的方式安裝java,執行hadoop時若有出現JAVA_HOME未配置的話,就要再export JAVA_HOME=/usr/local/jdk就可以了

若有顯示檔案根目錄(理論上跟web:50070所看到的目錄結構應該要一致)

Found 3 items
drwxr-xr-x – root supergroup 0 2017-06-27 16:39 hdfs://localhost:9000/exchange
drwxr-xr-x – root supergroup 0 2017-07-26 11:28 hdfs://localhost:9000/upload_files
drwxr-xr-x – root supergroup 0 2015-07-22 23:17 hdfs://localhost:9000/user

那就代表大功告成啦啦啦啦,後續直接對這個檔案系統操作的話,再參考相關指令集教學

例如上傳檔案的話,可以透過

~/hadoop-2.6.5/bin/hdfs dfs -put ~/test.txt hdfs://localhost:9000/upload_files

不過,馬上就會面臨到權限問題:

put: Permission denied: user=paul, access=WRITE, inode=”/test.txt._COPYING_”:root:supergroup:drwxr-xr-x

web就可以直接指定root,但linux連過去會依目前的使用者作為user

因此,可以得知,只要su到root,再執行/home/paul/hadoop-2.6.5/bin/hdfs dfs -put /home/paul/test.txt hdfs://localhost:9000/upload_files就可以了

drwxr-xr-x – root supergroup 0 2017-07-26 11:50 hdfs://localhost:9000/upload_files/exchange
-rw-r–r– 3 root supergroup 5 2017-07-27 01:29 hdfs://localhost:9000/upload_files/test.txt

至於要怎麼解決這個問題,包含透過使用者有自行的目錄權限,就還需要再研究了,等明天看看吧…時候不早了..

待閱讀:hadoop權限問題參考

在centOS上安裝Docker CE(Communtity Edition) – 記錄

在centOS上安裝Docker CE(Communtity Edition) – 記錄

基本上,copy自連結,純粹記錄指令,因為各家linux的預設程式安裝器不盡相同,這邊記錄centos版本:

移除舊的docker

$ sudo yum remove docker docker-common container-selinux docker-selinux docker-engine docker-engine-selinux

設定repository(Docker CE)

  1. 安裝必要的套件 yum-utils, yum-config-manager以及devicemapper所需要的storage driver:device-mapper-persistent-data and lvm2
    sudo yum install -y yum-utils device-mapper-persistent-data lvm2
  2. 啟用the extras CentOS repository. 確保能存取到docker-c所需要的container-selinux 套件
    $ sudo yum-config-manager –enable extras
  3. 設定 預設取得stable 版本的repository(建議預設,即使你要用edge的版本)
    sudo yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
  4. 選擇性: 啟用edge repository.
    $ sudo yum-config-manager –enable docker-ce-edge
  5. 若要關閉 the edge repository就使用 --disable 標籤,若要重新啟用,就使用enable標籤,以關閉為例:
    $ sudo yum-config-manager –disable docker-ce-edge

 

安裝docker

  1. 更新yum的套件清單
    $ sudo yum makecache fast
  2. 列出指定版本的docker清單
    $ yum list docker-ce.x86_64 –showduplicates |sort -r
  3. 安裝最新版本或是安裝特定版本的docker
    $ sudo yum install docker-ce
    or
    $ sudo yum install docker-ce-<VERSION>

    Warning: If you have multiple Docker repositories enabled, installing or updating without specifying a version in the yum install or yum update command will always install the highest possible version, which may not be appropriate for your stability needs.

  4. 編輯 /etc/docker/daemon.json. 好像是要配置存儲相關的設定,正式環境請見:連結{
    “storage-driver”: “devicemapper”
    }
  5. 啟動Docker.
    $ sudo systemctl start docker
  6. 可以驗證docker是否安裝正確,跑跑看docker的hello world的映象檔吧$ sudo docker run hello-world
Docker映像與資料備份與還原:以cassandra為例

Docker映像與資料備份與還原:以cassandra為例

今天開發的時候遇到一個情況,就是我的測試程式依賴了我本機起的一個nosql cassandra服務,是建立在docker上的

因此我把程式提供給同事以後,發現他沒有環境,因此程式功能無法展示,當然一部份也要展示cassandra的使用方式

 

一時間還不會docker的備份與移轉,因此早上就急著先把vmware的images(約略15GB)複製給同事,光複製的時間就花了快二十分鐘,當下覺得這種環境移轉的方式太過於笨重,想到若我還要再把我本機的另一個安裝hadoop的vm也要copy過去的話,那這樣來來回回的時間就不知耗費掉多少,而且我的私人開發環境其實是我自己常用的密碼,所以分享起來也是挺麻煩的。

 

有上述念頭後,我開始嘗試著在我兩台不同的vm(都是ubuntu)上面,試著把docker備份流程做一次

docker images備份(起手式:連結)

首先,我們需要先將目前的container狀態commit,先docker -ps列出所有container的id

我們很快的就看到dev-cassandra就是我們要備份的目標,接著輸入以下的指令:docker commit -p  {{container id}} {{repository-name}}

sudo docker commit -p  3b5 cassandra-devenv

接著回到docker images列表,我們就會看到我們的新commit的images已經被建立出來了(圖中第一個)

container已經被commit了以後,那我們要怎麼轉成實體檔案呢?

指令很簡單:

docker save -o ~/cassandra-devenv.tar cassandra-devenv

這個指令要跑一下子,跑完以後,我們可以看到tar檔已經產生,看起來要400mb左右,著實比vm動輒1x gb來得輕量許多

這裡有一個小陷阱,就是要先去chown給paul與chmod 給檔案合適的權限

 

備份docker的資料卷資料

images既然被備份出來以後,那我們的資料呢?

還記得dockers要怎麼看資料卷的現實綁定的位置呀?就要靠docker inspect 指令了

sudo docker inspect 3b5

看到container的環境資訊後,會發現幸好這個dockerfile有將資料獨立出來,在mount的字段下,我們可以看到/var/lib/cassandra的根目錄,被指派在我們本機(ubuntu)的/var/lib/docker/volumes/31a88f59c57b5a75b98f9c4e6a539e4140cb226760fc540b15b930d96010a84c/_data下。
(註:這邊不同系統的資料或設定目錄要視系統而定,不見得每個系統都有必要這樣做切割,但大部分有這樣切割設定的images佈署的彈性才會更好,也才會有更好使用率)

既然知道了cassandra相關檔案的實體位置,我們先將它備份壓縮起來吧。我已經可以想像等下要連同docker image的檔案與data要壓縮複製過去另一台主機。

先備份到個人目錄:

sudo cp -r /var/lib/docker/volumes/31a88f59c57b5a75b98f9c4e6a539e4140cb226760fc540b15b930d96010a84c /home/paul

記得要下-r,才會recursive的複製所有子目錄、檔案

這時/home/paul的目錄下就有了31a88f59c57b5a75b98f9c4e6a539e4140cb226760fc540b15b930d96010a84c

接著我們來進行打包成tar檔,tar的壓縮指令請參考:連結

tar -zcvf ./cassandra-data.tar ./31a88f59c57b5a75b98f9c4e6a539e4140cb226760fc540b15b930d96010a84c

建議可以使用加上-z的參數,代表,透過gzip的方式壓縮,若沒有-z或-j的話,是代表僅打包,不壓縮

ls -l看看壓完以後只剩下33MB,看起來效果不錯

 

既然都已經備份出來了,包含docker與資料的壓縮檔

那我們要怎麼從vm複製檔案到另一個vm呀?在我還沒學會scp指令前,我還真的只知道vm的linux開分享samba,然後透過windows去copy到另一台分享出來的目錄

以上動作,真的只需要1行指令就做的到了,那就是scp,我們先ssh到另一台目標移置的vm去!!

輸入scp指令看看使用方式:

usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
[-l limit] [-o ssh_option] [-P port] [-S program]
[[user@]host1:]file1 … [[user@]host2:]file2

scp是secure copy的簡寫,因此我們可以從首n台主機host 1 ~host n的檔案,複製到local來,以我們的例子來說,我們只要切到目標主機的指令目錄以後,照著以下輸入

同意建立ecdsa以後,接著輸入遠端的密碼,就會發現他開始copy了:

 scp paul@192.168.65.136:/home/paul/cassandra-data.tar ./ paul@192.168.65.136:/home/paul/cassandra-devenv.tar ./ 

restore docker的image

都搞定以後,我們輸入以下指令,就可以將這個備份load到這台vm的docker的images

sudo docker load -i ./cassandra-devenv.tar

不過怪異的是,不知有沒有參數可以指令輸入的repository name與tag,我load進來以後,預設是none。接著考慮本機的環境,我希望將cassandra的data目錄換一個位置:就到my/own/datadir吧,這邊沒有絕對名稱,只需要自己分的清楚,解壓縮以後,按照當初打包的相對位置先放置好:

tar -zxvf cassandra-data.tar

註:這邊我後來想想若在壓縮時,有透過-z的參數進行壓縮的話,建議命名就要是tar.gz,否則解壓端應該很難知道需不需要加上-z的參數,這邊因為都是我幹的,所以我當然知道要這樣搞。通通都解到目標目錄,接著看看目錄內容是不是都有了
(註:這邊我還省略了一些解壓目錄以後,再從目錄把檔案cp或mv到my/own/datadir的過程)

接著只要輸入神奇的docker run指令,就會發現

 sudo docker run –name cassandra-dev -p 9042:9042 -v /my/own/datadir:/var/lib/cassandra -d e86

檢查一下,sudo docker ps,已經正常跑起來了,這邊其實我有發現,cassandra的服務通常都要跑三分鐘左右,有時initialize掛掉都是發生在2~3分之間,通常超過3分鐘,應該就是起來了

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2cf14dc1d4d0 e86 “/docker-entrypoint.s” 6 hours ago Up 6 hours 7000-7001/tcp, 7199/tcp, 9160/tcp, 0.0.0.0:9042->9042/tcp cassandra-dev

 

實際連到192.168.65.130(剛剛是從136備份過來)的cassandra來看看囉!嗯~資料看起來都有被複製過來~暫時大功告成!特此記錄一番

 

後記:每次要寫這種過程重現真的是很耗費時間(也整理了差不多1個多小時),我發現,最佳的記錄方式,其實就是當我們在試著學習與除錯的時候(若有那個餘裕啦)

就定期把相關的畫面與做過的事情,記錄到evernote或其他方便的地方,事後的整理事實上真的事半功倍…若下次有機會遇到的話…希望有機會想到…

 

WP Facebook Auto Publish Powered By : XYZScripts.com