重新產生k8s join指令

因為新版的k8s的token已經有時間效期,
所以在安裝完後,隔一陣子想要加入新的節點就會出現舊的join token無法使用.
這時候可以用kubeadm token generate重新產生新的token,並用下列語法印出join指令.

kubeadm token create `kubeadm token generate` --print-join-command --ttl=0

MongoDB Replica Set高可用性的建置

1. 建立三個MongoDB

echo "[info] 建立測試環境";
docker network create mongo-cluster >/dev/null 2>&1
docker rm -f mongo1 mongo2 mongo3 >/dev/null 2>&1
for i in 1 2 3
do
  echo "       mongo${i} 建立"
  docker run \
    -d \
    -p 3000$i:27017 \
    --name mongo$i \
    --net mongo-cluster \
    mongo mongod --replSet my-mongo-set >/dev/null 2>&1
done

2. 接著設定三者關係,並強制設定electionTimeoutMillis為500ms.

echo "       設定mongo cluster"
docker exec -it mongo3 mongo --eval "config={\"_id\":\"my-mongo-set\",\"members\":[{\"_id\":0,\"host\":\"mongo1:27017\"},{\"_id\":1,\"host\":\"mongo2:27017\"},{\"_id\":2,\"host\":\"mongo3:27017\"}],\"settings\": { \"electionTimeoutMillis\": 500 }}; rs.initiate(config)"

3. PHP測試

#https://github.com/mongodb/mongo-php-library
require_once __DIR__ . "/vendor/autoload.php";

try{
  $client = new MongoDB\Client("mongodb://mongo1:27017,mongo2:27017,mongo3:27017",[],[
    'typeMap' => [
      'array' => 'array',
      'document' => 'array',
      'root' => 'array',
    ],
  ]);
  $db = $client->selectDatabase('test');
  $cursor = $db->command(['isMaster' => 1]);
  echo "[info] 成功連線至: {$cursor->toArray()[0]['primary']}\n";
  
} catch(Exception $e) {
  echo "[error] 無法線連\n";
  exit;
}

{  //若Collection:testA不存在則建立.
  if((iterator_count($db->listCollections([
    'filter'=>[
      'name'=>'testA'
    ]
  ])))==0) //當數量為0時,建立testA
    $db->createCollection('testA');
}

//連線至Collection:testA
$collection=$db->selectCollection('testA');

//若沒有任何資料,則建立100則隨機資料
if($collection->count()==0){
  for($i=0;$i<100;$i++){
    $insertOneResult = $collection->insertOne([
      'idx' => $i,
      'value' => "{$i}, rand: ".rand(0,9999),
    ]);
  }
}

//取得最後三筆資料
foreach($collection->find([],[
  'limit' => 3,
  'projection' => ['_id'=>0],
  'sort' => [
    'idx'=>-1
  ]
]) as $rs){
  echo "\tidx:{$rs['idx']}\tvalue:{$rs['value']}\n";
}

刪除無作用的docker image

在使用docker build建立image的過程中,往往會產生很多個none的docker images

因此可以透過下列指令刪除

docker rmi $(docker images | grep none | awk '{print $3}')

遷移gitlab

我自建的gitlab是跑在synology上,不過因為效能太差了
因此決定將gitlab移植到vm上.

之前測試了讓vm掛載synology網芳的gitlab data的資料夾,
但是都會發生權限的問題.

因此目前打算讓gitlab data的資料夾也放在vm的本機端.
再透過定期備份的方式,來保全資料.
以下是我移機的紀錄

備份

docker exec -it gitlab gitlab-rake gitlab:backup:create

還原-前置工作
建立資料夾

mkdir -p $PWD/files/data/backups
mkdir -p $PWD/files/conf
mkdir -p $PWD/files/log/

複製備份資料

cp $OLD_GITLAB_PATH/backups/1510018625_2017_11_07_10.1.0_gitlab_backup.tar $PWD/files/data/backups

執行新的gitlab

docker run -d \
  --name=gitlab \
  --publish 443:443 \
  --publish 80:80 \
  --restart always \
  -v $PWD/files/conf:/etc/gitlab \
  -v $PWD/files/log:/var/log/gitlab \
  -v $PWD/files/data:/var/opt/gitlab \
  gitlab/gitlab-ce:10.1.0-ce.0

等待兩三分鐘後,確定可以進入gitlab web ui介面後
開始進入還原工作

還原
進入container

docker exec -it gitlab bash

停止服務

gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq

設定權限

chmod 777 /var/opt/gitlab/backups/1510018625_2017_11_07_10.1.0_gitlab_backup.tar

還原

gitlab-rake gitlab:backup:restore BACKUP=1510018625_2017_11_07_10.1.0

重啟服務

gitlab-ctl restart

check

gitlab-rake gitlab:check SANITIZE=true

QGIS Container

for Mac OS

#取得IP
IP=$(ipconfig getifaddr en0)
#設定X11
open -a XQuartz &
nohup socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\" >/dev/null 2>&1 &
#執行qgis container
docker run -it --rm \
  -e DISPLAY=$IP:0 \
  --volume="$HOME/.Xauthority:/root/.Xauthority:rw" \
  -v /tmp/.X11-unix:/tmp/.X11-unix \
  slanla/qgis:latest

ubuntu 16.04 安裝kubernetes 1.8.1

前置工作
安裝kubectl

sudo rm ./kubectl /usr/local/bin/kubectl
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl

設定kubeadm來源

sudo apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo bash -c 'cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF'

安裝kubeadm

sudo apt-get update && sudo apt-get install -y kubelet kubeadm

關閉swap

sudo swapoff -a 
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
sudo mount -a

安裝步驟:

##############################################################################################
##
## init
##
sudo kubeadm init \
  --kubernetes-version=v1.8.1 \
  --pod-network-cidr=10.244.0.0/16 \
  --skip-preflight-checks

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

kubectl get pods --all-namespaces -o wide

############################################################################################
##
## 安裝網路
##
kubectl apply -f https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')

############################################################################################
##
## 加入節點
##
sudo kubeadm join --token xxxxxxxxxxxxxxxxxxxx \
  10.1.1.1:6443 \
  --discovery-token-ca-cert-hash sha256:yyyyyyyyyyyyyyyyyyyy
mkdir -p $HOME/.kube
scp 10.1.1.1:~/.kube/config $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes


############################################################################################
##
## 加入dashboard, 參考來源: https://github.com/kubernetes/dashboard/wiki/Access-control 
##
cat <<EOF > dashboard-admin.yaml
{
  "apiVersion": "rbac.authorization.k8s.io/v1beta1", 
  "kind": "ClusterRoleBinding", 
  "metadata": {
    "name": "kubernetes-dashboard",
    "labels": {
      "k8s-app": "kubernetes-dashboard"
    }
  },
  "roleRef": {
    "apiGroup": "rbac.authorization.k8s.io", 
    "kind": "ClusterRole", 
    "name": "cluster-admin"
  }, 
  "subjects": [
    {
      "kind": "ServiceAccount", 
      "name": "kubernetes-dashboard",
      "namespace": "kube-system"
    }
  ]
}
EOF
kubectl apply -f dashboard-admin.yaml 
rm dashboard-admin.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml

############################################################################################
##
## 加入proxy
##
nohup kubectl proxy --address 0.0.0.0 --accept-hosts '.*' >/dev/null 2>&1 &

############################################################################################
##
## 取得kubernetes-dashboard-admin登入dashboard的token (暫時用不到)
##
## kubectl describe -n kube-system secret/$(kubectl -n kube-system get secret | grep kubernetes-dashboard-admin | awk {'print $1'}) | grep token: | awk {'print $2'}

安裝kubernetes 1.7.5於ubuntu16.04

環境介紹:

hostname os ip note
node-k00 ubuntu16.04 10.1.200.100 kubernetes master
node-k01 ubuntu16.04 10.1.200.101 kubernetes node
node-k02 ubuntu16.04 10.1.200.102 kubernetes node
node-k03 ubuntu16.04 10.1.200.103 kubernetes node

1.首先在master以及node上安裝kubectl

curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.7.5/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl

2.安裝kubeadm (在master)

sudo apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo bash -c 'cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF'
sudo apt-get update && sudo apt-get install -y kubelet kubeadm

3.使用kubeadm初始化kubernetes (在master)

sudo kubeadm init --kubernetes-version=v1.8.0 --pod-network-cidr 10.244.0.0/16

4.複製設定檔 (在master)

mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

5.等待一段時間後,使用下列指令確認一下pod部署狀態 (在master).

kubectl get pods --all-namespaces -o wide

6.建立網路 (在master)

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

並等待一段時間後,使用下列指令確認一下pod部署狀態 (在master).

kubectl get pods --all-namespaces -o wide

7.加入 dashboard-admin, 參考來源 (在master)

cat <<EOF > dashboard-admin.yaml
{
  "apiVersion": "rbac.authorization.k8s.io/v1beta1", 
  "kind": "ClusterRoleBinding", 
  "metadata": {
    "name": "kubernetes-dashboard",
    "labels": {
      "k8s-app": "kubernetes-dashboard"
    }
  },
  "roleRef": {
    "apiGroup": "rbac.authorization.k8s.io", 
    "kind": "ClusterRole", 
    "name": "cluster-admin"
  }, 
  "subjects": [
    {
      "kind": "ServiceAccount", 
      "name": "kubernetes-dashboard",
      "namespace": "kube-system"
    }
  ]
}
EOF
kubectl create -f dashboard-admin.yaml
rm dashboard-admin.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml

並等待一段時間後,使用下列指令確認一下pod部署狀態 (在master).

kubectl get pods --all-namespaces -o wide

8.建立proxy,讓瀏覽器可以開始dashboard (在master)

nohup kubectl proxy --address 0.0.0.0 --accept-hosts '.*' >/dev/null 2>&1 &

9.開啟kubenetes dashboard (在10.1.0.0/16的網域內)

http://10.1.200.100:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/

10.加入Nginx Backend (在master)

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress/master/examples/deployment/nginx/default-backend.yaml

11.加入 Ingress RBAC 認證 (在master)

curl -O https://raw.githubusercontent.com/kubernetes/ingress/master/examples/rbac/nginx/nginx-ingress-controller-rbac.yml
## 修改 namespace
sed -i 's/namespace: nginx-ingress/namespace: kube-system/g' nginx-ingress-controller-rbac.yml
## 匯入yaml檔案
kubectl apply -f nginx-ingress-controller-rbac.yml
rm -r nginx-ingress-controller-rbac.yml

12.加入 Ingress Controller (在master)

curl -O https://raw.githubusercontent.com/kubernetes/ingress/master/examples/daemonset/nginx/nginx-ingress-daemonset.yaml
## 修改 namespace
sed -i 's/terminationGracePeriodSeconds/hostNetwork: true\n      serviceAccountName: nginx-ingress-serviceaccount\n      terminationGracePeriodSeconds/g' nginx-ingress-daemonset.yaml
## 匯入yaml檔案
kubectl apply -f nginx-ingress-daemonset.yaml
rm nginx-ingress-daemonset.yaml
kubectl get daemonset -n kube-system nginx-ingress-lb

13.加入其他的node (在master)

token=$(sudo kubeadm token list | grep authentication,signing | awk '{print $1}')
ssh 10.1.200.101 "sudo kubeadm join --token $token 10.1.200.100:6443"
ssh 10.1.200.102 "sudo kubeadm join --token $token 10.1.200.100:6443"
ssh 10.1.200.103 "sudo kubeadm join --token $token 10.1.200.100:6443"