This blog is part of a multi-part blog series that shows how to run your applications on Kubernetes. It will use the Couchbase, an open source NoSQL distributed document database, as the Docker container.
- Part 1 explained how to start Kubernetes cluster using Vagrant – Kubernetes on Vagrant
- Part 2 did the same for Amazon Web Services – Kubernetes on Amazon Web Services
- Part 3 did the same for Google Cloud – Kubernetes on Google Cloud
This fourth part will show:
- How to setup and start the Kubernetes cluster on Azure
- Run Docker container in the Kubernetes cluster
- Expose Pod on Kubernetes as Service
- Shutdown the cluster
Many thanks to @colemickens for helping me through this recipe. This blog content is heavily based upon the instructions at colemickens.github.io/docs/getting-started-guides/azure/.
Install and Configure Azure CLI
Azure CLI is a command-line interface to develop, deploy and manage Azure applications. This is needed in order to install Kubernetes cluster on Azure.
- Install Node:
1234567891011121314151617brew install node==> Downloading https://homebrew.bintray.com/bottles/node-6.2.0.yosemite.bottle.tar.gz######################################################################## 100.0%==> Pouring node-6.2.0.yosemite.bottle.tar.gz==> CaveatsPlease note by default only English locale support is provided. If you needfull locale support you should either rebuild with full icu:`brew reinstall node --with-full-icu`or add full icu data at runtime following:https://github.com/nodejs/node/wiki/Intl#using-and-customizing-the-small-icu-buildBash completion has been installed to:/usr/local/etc/bash_completion.d==> Summary🍺 /usr/local/Cellar/node/6.2.0: 3,979 files, 40.4M - Install Azure CLI:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288npm install -g azure-cli/usr/local/bin/azure -> /usr/local/lib/node_modules/azure-cli/bin/azure> fibers@1.0.13 install /usr/local/lib/node_modules/azure-cli/node_modules/fibers> node build.js || nodejs build.js`darwin-x64-v8-5.0` exists; testingBinary is fine; exiting/usr/local/lib└─┬ azure-cli@0.10.0├─┬ adal-node@0.1.17│ ├── date-utils@1.2.21│ ├─┬ jws@3.1.3│ │ ├─┬ base64url@1.0.6│ │ │ └─┬ meow@2.0.0│ │ │ ├─┬ camelcase-keys@1.0.0│ │ │ │ ├── camelcase@1.2.1│ │ │ │ └── map-obj@1.0.1│ │ │ ├─┬ indent-string@1.2.2│ │ │ │ ├── get-stdin@4.0.1│ │ │ │ └─┬ repeating@1.1.3│ │ │ │ └── is-finite@1.0.1│ │ │ ├── minimist@1.2.0│ │ │ └── object-assign@1.0.0│ │ └─┬ jwa@1.1.3│ │ ├── buffer-equal-constant-time@1.0.1│ │ └─┬ ecdsa-sig-formatter@1.0.5│ │ └── base64-url@1.2.2│ ├── node-uuid@1.4.1│ ├── xmldom@0.1.22│ └── xpath.js@1.0.6├── applicationinsights@0.15.12├── async@1.4.2├── azure-arm-authorization@2.0.0├── azure-arm-batch@0.1.0├── azure-arm-cdn@0.1.0-preview├── azure-arm-commerce@0.1.1├── azure-arm-compute@0.18.0├── azure-arm-datalake-analytics@0.3.2├── azure-arm-datalake-store@0.3.0├── azure-arm-dns@0.10.1├── azure-arm-hdinsight@0.2.0├── azure-arm-hdinsight-jobs@0.1.0├── azure-arm-insights@0.11.1├── azure-arm-network@0.13.1├── azure-arm-rediscache@0.2.1├── azure-arm-resource@1.4.4-preview├── azure-arm-storage@0.13.1-preview├── azure-arm-trafficmanager@0.10.5├─┬ azure-arm-website@0.10.0│ ├─┬ azure-common@0.9.12│ │ ├─┬ request@2.45.0│ │ │ ├── aws-sign2@0.5.0│ │ │ ├── bl@0.9.5│ │ │ ├── caseless@0.6.0│ │ │ ├── forever-agent@0.5.2│ │ │ ├─┬ form-data@0.1.4│ │ │ │ ├── async@0.9.2│ │ │ │ └─┬ combined-stream@0.0.7│ │ │ │ └── delayed-stream@0.0.5│ │ │ ├─┬ hawk@1.1.1│ │ │ │ ├── boom@0.4.2│ │ │ │ ├── cryptiles@0.2.2│ │ │ │ ├── hoek@0.9.1│ │ │ │ └── sntp@0.2.4│ │ │ ├─┬ http-signature@0.10.1│ │ │ │ ├── asn1@0.1.11│ │ │ │ └── assert-plus@0.1.5│ │ │ ├── mime-types@1.0.2│ │ │ ├── node-uuid@1.4.7│ │ │ ├── oauth-sign@0.4.0│ │ │ └── qs@1.2.2│ │ └── xml2js@0.2.7│ └── moment@2.6.0├── azure-asm-compute@0.15.0├── azure-asm-hdinsight@0.10.2├── azure-asm-mgmt@0.10.1├── azure-asm-network@0.11.0├── azure-asm-sb@0.10.1├── azure-asm-sql@0.10.1├── azure-asm-storage@0.10.1├── azure-asm-subscription@0.10.1├── azure-asm-trafficmanager@0.10.3├─┬ azure-asm-website@0.10.1│ └── moment@2.6.0├── azure-batch@0.3.0├─┬ azure-common@0.9.16│ ├── dateformat@1.0.2-1.2.3│ ├── duplexer@0.1.1│ ├── envconf@0.0.4│ ├─┬ request@2.45.0│ │ ├── aws-sign2@0.5.0│ │ ├── bl@0.9.5│ │ ├── caseless@0.6.0│ │ ├── forever-agent@0.5.2│ │ ├─┬ form-data@0.1.4│ │ │ ├── async@0.9.2│ │ │ ├─┬ combined-stream@0.0.7│ │ │ │ └── delayed-stream@0.0.5│ │ │ └── mime@1.2.11│ │ ├─┬ hawk@1.1.1│ │ │ ├── boom@0.4.2│ │ │ ├── cryptiles@0.2.2│ │ │ ├── hoek@0.9.1│ │ │ └── sntp@0.2.4│ │ ├─┬ http-signature@0.10.1│ │ │ ├── asn1@0.1.11│ │ │ ├── assert-plus@0.1.5│ │ │ └── ctype@0.5.3│ │ ├── mime-types@1.0.2│ │ ├── node-uuid@1.4.7│ │ ├── oauth-sign@0.4.0│ │ └── qs@1.2.2│ ├── validator@3.22.2│ └── xml2js@0.2.7├── azure-gallery@2.0.0-pre.18├── azure-graph@0.1.1├─┬ azure-keyvault@0.10.1│ └── node-uuid@1.4.7├─┬ azure-monitoring@0.10.2│ └── moment@2.6.0├─┬ azure-storage@0.7.0│ ├── browserify-mime@1.2.9│ ├── extend@1.2.1│ ├── node-uuid@1.4.7│ ├─┬ readable-stream@2.0.6│ │ ├── isarray@1.0.0│ │ ├── process-nextick-args@1.0.7│ │ └── util-deprecate@1.0.2│ ├─┬ request@2.57.0│ │ ├── aws-sign2@0.5.0│ │ ├─┬ bl@0.9.5│ │ │ └─┬ readable-stream@1.0.34│ │ │ └── isarray@0.0.1│ │ ├── caseless@0.10.0│ │ ├─┬ form-data@0.2.0│ │ │ ├── async@0.9.2│ │ │ └─┬ combined-stream@0.0.7│ │ │ └── delayed-stream@0.0.5│ │ ├─┬ har-validator@1.8.0│ │ │ ├── bluebird@2.10.2│ │ │ └── commander@2.9.0│ │ ├── hawk@2.3.1│ │ ├─┬ http-signature@0.11.0│ │ │ ├── asn1@0.1.11│ │ │ └── assert-plus@0.1.5│ │ ├─┬ mime-types@2.0.14│ │ │ └── mime-db@1.12.0│ │ └── qs@3.1.0│ ├── validator@3.22.2│ └── xml2js@0.2.7├─┬ caller-id@0.1.0│ └── stack-trace@0.0.9├── colors@0.6.2├─┬ commander@1.0.4│ └── keypress@0.1.0├── easy-table@0.0.1├─┬ event-stream@3.1.5│ ├── from@0.1.3│ ├── map-stream@0.1.0│ ├── pause-stream@0.0.11│ ├── split@0.2.10│ └── stream-combiner@0.0.4├── eyes@0.1.8├── fast-json-patch@0.5.6├── github@0.1.6├── js2xmlparser@1.0.0├── jsrsasign@4.8.2├─┬ kuduscript@1.0.6│ ├── commander@1.1.1│ └── streamline@0.4.11├── moment@2.13.0├── ms-rest@1.14.2├─┬ ms-rest-azure@1.14.2│ ├── async@0.2.7│ └── uuid@2.0.1├── node-forge@0.6.23├── node-uuid@1.2.0├── number-is-nan@1.0.0├── omelette@0.1.0├─┬ openssl-wrapper@0.2.1│ ├── debug@0.7.4│ └── q@0.9.7├─┬ read@1.0.7│ └── mute-stream@0.0.6├─┬ readable-stream@1.0.34│ ├── core-util-is@1.0.2│ ├── inherits@2.0.1│ ├── isarray@0.0.1│ └── string_decoder@0.10.31├─┬ request@2.69.0│ ├── aws-sign2@0.6.0│ ├── aws4@1.4.1│ ├─┬ bl@1.0.3│ │ └─┬ readable-stream@2.0.6│ │ └── isarray@1.0.0│ ├── caseless@0.11.0│ ├─┬ combined-stream@1.0.5│ │ └── delayed-stream@1.0.0│ ├── extend@3.0.0│ ├── forever-agent@0.6.1│ ├─┬ form-data@1.0.0-rc4│ │ └── async@1.5.2│ ├─┬ har-validator@2.0.6│ │ ├─┬ chalk@1.1.3│ │ │ ├── ansi-styles@2.2.1│ │ │ ├── escape-string-regexp@1.0.5│ │ │ ├─┬ has-ansi@2.0.0│ │ │ │ └── ansi-regex@2.0.0│ │ │ ├── strip-ansi@3.0.1│ │ │ └── supports-color@2.0.0│ │ ├─┬ commander@2.9.0│ │ │ └── graceful-readlink@1.0.1│ │ ├─┬ is-my-json-valid@2.13.1│ │ │ ├── generate-function@2.0.0│ │ │ ├─┬ generate-object-property@1.2.0│ │ │ │ └── is-property@1.0.2│ │ │ ├── jsonpointer@2.0.0│ │ │ └── xtend@4.0.1│ │ └─┬ pinkie-promise@2.0.1│ │ └── pinkie@2.0.4│ ├─┬ hawk@3.1.3│ │ ├── boom@2.10.1│ │ ├── cryptiles@2.0.5│ │ ├── hoek@2.16.3│ │ └── sntp@1.0.9│ ├─┬ http-signature@1.1.1│ │ ├── assert-plus@0.2.0│ │ ├─┬ jsprim@1.2.2│ │ │ ├── extsprintf@1.0.2│ │ │ ├── json-schema@0.2.2│ │ │ └── verror@1.3.6│ │ └─┬ sshpk@1.8.3│ │ ├── asn1@0.2.3│ │ ├── assert-plus@1.0.0│ │ ├─┬ dashdash@1.13.1│ │ │ └── assert-plus@1.0.0│ │ ├── ecc-jsbn@0.1.1│ │ ├─┬ getpass@0.1.6│ │ │ └── assert-plus@1.0.0│ │ ├── jodid25519@1.0.2│ │ ├── jsbn@0.1.0│ │ └── tweetnacl@0.13.3│ ├── is-typedarray@1.0.0│ ├── isstream@0.1.2│ ├── json-stringify-safe@5.0.1│ ├─┬ mime-types@2.1.11│ │ └── mime-db@1.23.0│ ├── node-uuid@1.4.7│ ├── oauth-sign@0.8.2│ ├── qs@6.0.2│ ├── stringstream@0.0.5│ ├── tough-cookie@2.2.2│ └── tunnel-agent@0.4.3├─┬ ssh-key-to-pem@0.11.0│ ├── asn1@0.1.11│ └── ctype@0.5.2├─┬ streamline@0.10.17│ ├── fibers@1.0.13│ ├── galaxy@0.1.12│ └─┬ source-map@0.1.43│ └── amdefine@1.0.0├── streamline-streams@0.1.5├─┬ sync-request@3.0.0│ ├─┬ concat-stream@1.4.10│ │ ├── readable-stream@1.1.14│ │ └── typedarray@0.0.6│ ├── http-response-object@1.1.0│ └─┬ then-request@2.2.0│ ├── http-basic@2.5.1│ ├─┬ promise@7.1.1│ │ └── asap@2.0.4│ └── qs@6.2.0├── through@2.3.4├── tunnel@0.0.2├── underscore@1.4.4├── validator@3.1.0├─┬ winston@0.6.2│ ├── async@0.1.22│ ├── cycle@1.0.3│ ├── pkginfo@0.2.3│ └── request@2.9.203├── wordwrap@0.0.2├─┬ xml2js@0.1.14│ └── sax@0.5.2└── xmlbuilder@0.4.3 - Sign up for free trial at https://azure.microsoft.com/en-us/free/.
- Login to Azure using the command
azure login
:
123456789azure logininfo: Executing command login\info: To sign in, use a web browser to open the page https://aka.ms/devicelogin. Enter the code BS5P64ANU to authenticate.|info: Added subscription Free Trialinfo: Setting subscription "Free Trial" as default+info: login command OK - Get account information using
azure account show
command:
123456789101112131415azure account showinfo: Executing command account showdata: Name : Free Trialdata: ID : XXXdata: State : Enableddata: Tenant ID : YYYdata: Is Default : truedata: Environment : AzureClouddata: Has Certificate : Nodata: Has Access Token : Yesdata: User name : arun.gupta@gmail.comdata:info: account show command OK
Start Kubernetes Cluster
- Download Kubernetes 1.2.4 and extract it.
- Kubernetes cluster on Azure can be started as:
123456export KUBERNETES_PROVIDER=azureexport AZURE_SUBSCRIPTION_ID=XXXexport AZURE_TENANT_ID=YYY./cluster/kube-up.shXXX
andYYY
from the previous command.AZURE_SUBSCRIPTION_ID
andAZURE_TENANT_ID
are specific to Azure.These values can also be edited in
cluster/azure/config-default.sh
. - Start Kubernetes cluster:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950./kubernetes/cluster/kube-up.sh... Starting cluster using provider: azure... calling verify-prereqs... calling kube-up++> AZURE KUBE-UP STARTED: Tue May 31 16:15:26 PDT 2016This will be interactive. (export AZURE_AUTH_METHOD=client_secret to avoid the prompt)hyperkube-amd64:v1.2.4 was found in the gcr.io/google_containers repositoryFlag --tenant-id has been deprecated, tenant-id is deprecated. it is now determined automatically from the subscription idWARN[0000] --resource-group is unset. Derived one from --deployment-name: "kube-20160531-161525"WARN[0000] --master-fqdn is unset. Derived one from input: "kube-20160531-161525.westus.cloudapp.azure.com".To sign in, use a web browser to open the page https://aka.ms/devicelogin. Enter the code BPRLH2ARJ to authenticate.INFO[0034] Starting ARM Deployment. This will take some time. deployment="kube-20160531-161525-1464736561"INFO[0279] Finished ARM Deployment. deployment="kube-20160531-161525-1464736561"INFO[0279] Validating Kubernetes cluster.WARN[0279] Failed to validate components: Get https://kube-20160531-161525.westus.cloudapp.azure.com:6443/api/v1/componentstatuses: dial tcp 23.99.60.138:6443: getsockopt: connection refusedINFO[0294] Validating Kubernetes cluster.WARN[0294] Failed to validate components: Get https://kube-20160531-161525.westus.cloudapp.azure.com:6443/api/v1/componentstatuses: dial tcp 23.99.60.138:6443: getsockopt: connection refusedINFO[0309] Validating Kubernetes cluster.WARN[0309] Failed to validate components: Get https://kube-20160531-161525.westus.cloudapp.azure.com:6443/api/v1/componentstatuses: dial tcp 23.99.60.138:6443: getsockopt: connection refusedINFO[0324] Validating Kubernetes cluster.WARN[0347] validate: incorrect healthy count. expected=3 actual=4INFO[0347] Deployment Complete!INFO[0347] master: "https://kube-20160531-161525.westus.cloudapp.azure.com:6443"INFO[0347] output: "/opt/azkube/_deployments/kube-20160531-161525"cluster "kube-20160531-161525" set.user "kube-20160531-161525_user" set.context "kube-20160531-161525" set.switched to context "kube-20160531-161525".++> AZURE KUBE-UP FINISHED: Tue May 31 16:21:15 PDT 2016 (duration: -349 seconds)... calling validate-clusterDetected 4 ready nodes, found 4 nodes out of expected 3. Found more nodes than expected, your cluster may not behave correctly.Found 4 node(s).NAME STATUS AGEkube-20160531-161525-vm-master Ready,SchedulingDisabled 21skube-20160531-161525-vm-node-0 Ready 18skube-20160531-161525-vm-node-1 Ready 19skube-20160531-161525-vm-node-2 Ready 19sFlag --api-version has been deprecated, flag is no longer respected and will be deleted in the next releaseValidate output:NAME STATUS MESSAGE ERRORscheduler Healthy okcontroller-manager Healthy oketcd-1 Healthy {"health": "true"}etcd-0 Healthy {"health": "true"}Cluster validation succeededDone, listing cluster services:Kubernetes master is running at https://kube-20160531-161525.westus.cloudapp.azure.com:6443
It starts four nodes of
Standard_A1
size. Each node gives you 1 core, 1.75 GB RAM, and 40GB HDD.
Run Docker Container in Kubernetes Cluster on Azure
Now that the cluster is up and running, get a list of all the nodes:
1
2
3
4
5
6
7
8
|
./kubernetes/cluster/kubectl.sh get no
NAME STATUS AGE
kube-20160531-161525-vm-master Ready,SchedulingDisabled 3m
kube-20160531-161525-vm-node-0 Ready 3m
kube-20160531-161525-vm-node-1 Ready 3m
kube-20160531-161525-vm-node-2 Ready 3m
|
Four instances are created as shown – one for master node and three for worker nodes.
Azure Portal shows all the created artifacts in the Resource Group:
More details about the created nodes is available:
Create a Couchbase pod:
1
2
3
4
|
./kubernetes/cluster/kubectl.sh run couchbase --image=arungupta/couchbase
deployment "couchbase" created
|
Notice, how the image name can be specified on the CLI. Kubernetes pre-1.2 versions created a Replication Controller with this command. This is explained in Kubernetes on Amazon Web Services or Kubernetes on Google Cloud. Kubernetes 1.2 introduced Deployments and so this creates a Deployment instead. This enables simplified application deployment and management including versioning, multiple simultaneous rollouts, aggregating status across all pods, maintaining application availability and rollback.
The pod uses arungupta/couchbase Docker image that provides a pre-configured Couchbase server. Any Docker image can be specified here.
Status of the pod can be watched:
1
2
3
4
5
6
7
|
./kubernetes/cluster/kubectl.sh get -w po
NAME READY STATUS RESTARTS AGE
couchbase-2830197765-f0s9c 0/1 ContainerCreating 0 5s
NAME READY STATUS RESTARTS AGE
couchbase-2830197765-f0s9c 1/1 Running 0 1m
|
Get more details about the pod:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
./kubernetes/cluster/kubectl.sh describe po couchbase-2830197765-f0s9c
Name: couchbase-2830197765-f0s9c
Namespace: default
Node: kube-20160531-161525-vm-node-2/10.0.0.6
Start Time: Tue, 31 May 2016 16:28:02 -0700
Labels: pod-template-hash=2830197765,run=couchbase
Status: Running
IP: 10.2.74.2
Controllers: ReplicaSet/couchbase-2830197765
Containers:
couchbase:
Container ID: docker://eba043085c95645cf650206469be5c7e2d6c7395883a053d197446a14e757440
Image: arungupta/couchbase
Image ID: docker://sha256:f6b013d9694354148ace6804127dadee01c733151b5ff5e169f7c3b0e4faf321
Port:
QoS Tier:
cpu: BestEffort
memory: BestEffort
State: Running
Started: Tue, 31 May 2016 16:29:04 -0700
Ready: True
Restart Count: 0
Environment Variables:
Conditions:
Type Status
Ready True
Volumes:
default-token-ylszs:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-ylszs
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
7m 7m 1 {default-scheduler } Normal Scheduled Successfully assigned couchbase-2830197765-f0s9c to kube-20160531-161525-vm-node-2
7m 7m 1 {kubelet kube-20160531-161525-vm-node-2} spec.containers{couchbase} Normal Pulling pulling image "arungupta/couchbase"
6m 6m 1 {kubelet kube-20160531-161525-vm-node-2} spec.containers{couchbase} Normal Pulled Successfully pulled image "arungupta/couchbase"
6m 6m 1 {kubelet kube-20160531-161525-vm-node-2} spec.containers{couchbase} Normal Created Created container with docker id eba043085c95
6m 6m 1 {kubelet kube-20160531-161525-vm-node-2} spec.containers{couchbase} Normal Started Started container with docker id eba043085c95
|
Expose Pod on Kubernetes as Service
Now that our pod is running, how do I access the Couchbase server? You need to expose the Deployment as a Service outside the Kubernetes cluster.
Typically, this will be exposed using the command:
1
2
3
|
./kubernetes/cluster/kubectl.sh expose deployment couchbase --target-port=8091 --port=8091 --type=LoadBalancer
|
But Azure does not support --type=LoadBalancer
at this time. This feature is being worked upon and will hopefully be available in the near future. So in the meanwhile, we’ll expose the Service as:
1
2
3
4
|
./kubernetes/cluster/kubectl.sh expose deployment couchbase --target-port=8091 --port=8091
service "couchbase" exposed
|
Now proxy to this Service using kubectl proxy
command:
1
2
3
4
|
./kubernetes/cluster/kubectl.sh proxy --address='0.0.0.0' --port=9999 --accept-hosts='.*'
Starting to serve on [::]:9999
|
And now this exposed Service is accessible at http://127.0.0.1:9999/api/v1/proxy/namespaces/default/services/couchbase/index.html. This shows the login screen of Couchbase Web Console:
Shutdown Kubernetes Cluster
Finally, shutdown the cluster using cluster/kube-down.sh
script.
1
2
3
4
5
6
7
8
9
|
./kubernetes/cluster/kube-down.sh
Bringing down cluster using provider: azure
Bringing down cluster
You must do this manually (for now)!
This can be done with:
./kubernetes/cluster/../cluster/../cluster/azure/util.sh: line 246: AZ_RESOURCE_GROUP: unbound variable
|
This script shuts down the cluster but the Azure resource group need to be explicitly removed. This can be done by selecting the Resource Group from portal.azure.com:
This is filed as #26601.
Enjoy!
Further references …
- Couchbase Server Developer Portal
- Couchbase on Containers
- Questions on StackOverflow, Forums or Slack Channel
- Follow us @couchbasedev
- Couchbase 4.5 Beta
Source: http://blog.couchbase.com/2016/june/kubernetes-cluster-azure-couchbase-service
The great info is available for all windows user here https://fixforwindows.com/sync it is the best online tutorial and there given instructions are helping from access windows sync setting. there you are easily arrange many device settings.
The article you have shared here very awesome. I really like and appreciated your work. I read deeply your article, the points you have mentioned in this article are useful