Posts

Showing posts from May, 2021

Ansistrano (Ansible + Capistrano): Quick Start

In this post, I am going to try Ansistrano to deploy a file on a web server. (See this post  this post  for detail about Ansible) what is Ansistrano? " ansistrano.deploy and ansistrano.rollback are Ansible roles to easily manage the deployment process for scripting applications such as PHP, Python and Ruby. It's an Ansible port for Capistrano." ( https://github.com/ansistrano/deploy ) install %  ansible-galaxy install ansistrano.deploy ansistrano.rollback create test file % mkdir -p public_html  % echo 'hello' > public_html/index.html  deploy % vim playbook.yml --- - name: deploy code hosts: webservers become: true vars: ansistrano_deploy_from: "{{ playbook_dir }}/public_html/" ansistrano_deploy_to: "/var/www/my-app" ansistrano_keep_releases: 3 ansistrano_deploy_via: "rsync" roles: - ansistrano.deploy See  https://github.com/ansistrano/deploy for the vars to customize as needed. Run the playbook.

Spring Sample on Docker (for M1 Chip)

In this post, I am going to run a sample Spring application, which was created at:  REST with Spring: Quick Start  . Assuming that you have the jar file at: ./build/libs/rest-service-0.0.1-SNAPSHOT.jar Prepare Docker Files % vim Dockerfile FROM arm64v8/openjdk ADD ./build/libs/rest-service-0.0.1-SNAPSHOT.jar greeting.jar CMD java -jar greeting.jar Note: arm64v8/openjdk is for M1 Chip. This solved the following build error: "The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8)" % vim docker-compose.yml version: "3.9" services: web: build: . ports: - "80:8080" Build & Run % docker-compose up --build % curl http://localhost/greeting {"id":1,"content":"Hello, World!"}

Kubernetes: Declarative vs Imperative (Nginx Example on Minikube)

Image
In this post, I am going to run a Nginx example on Minikube in two ways: 1. declarative: kubectl apply -f [yaml] 2. imperative: kubectl create & expose declarative: kubectl apply -f [yaml] With a declarative way, you can define the resources as yamls and apply them. This is preferable in a long run, but could be tedious if you just want to run it as a test. % cat deploy.yaml apiVersion: apps/v1 kind: Deployment metadata:   labels:     app: nginx   name: nginx spec:   replicas: 1   selector:     matchLabels:       app: nginx   template:     metadata:       labels:         app: nginx     spec:       containers:       - image: nginx         name: nginx % cat service.yaml apiVersion: v1 kind: Service metadata:   labels:     app: nginx   name: nginx spec:   ports:   - port: 80     protocol: TCP     targetPort: 80   selector:     app: nginx   type: NodePort % kubectl apply -f deploy.yaml % kubectl apply -f service.yaml open nginx % minikube service nginx ... | default   | nginx |       

kubectx & kubens: Quick Start

This post shows examples of kubectx & kubens. install % brew install kubectx This will install both kubectx and kubens. kubectx kubectx help manage k8s contexts. % kubectx -h USAGE:   kubectx                       : list the contexts   kubectx <NAME>                : switch to context <NAME>   kubectx -                     : switch to the previous context   ... Listing the contexts is as simple as follows: % kubectl config get-contexts CURRENT   NAME        CLUSTER     AUTHINFO    NAMESPACE *         kind-kind   kind-kind   kind-kind              minikube    minikube    minikube    default % kubectx kind-kind minikube Change the context: % kubectx minikube Switched to context "minikube". % kubectx          kind-kind minikube % kubectx - Switched to context "kind-kind". % kubectx   kind-kind minikube kubens kubens help manage k8s namaepaces (ns). % kubens -h      USAGE:   kubens                    : list the namespaces in the current context   kubens

Minikube Installation for M1 Mac

Image
In this post, I am going to try Minikube on Mac with M1 Chip. what is minikube Minikube is k8s tool running on a local machine. See also kind  for multi cluster implementation for local k8s. install % curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-arm64 % install minikube-darwin-arm64 /usr/local/bin/minikube % minikube version  minikube version: v1.20.0  Note: Installing with brew fails due to a different binary as of 2021-05-24. % brew install minikube % minikube version ❌  Exiting due to MK_WRONG_BINARY_M1: You are trying to run amd64 binary on M1 system. Please use darwin/arm64 binary instead (Download at https://github.com/kubernetes/minikube/releases/download/v1.20.0/minikube-darwin-amd64.) % brew uninstall minikube start The default driver 'virtualbox' is not supported on M1, but you can use 'docker' driver:  https://minikube.sigs.k8s.io/docs/drivers/docker/  . Make sure docker is running, and then specify the driver when starting

Java Data Structure Cheat Sheet - Hash Table

HashMap is the hash table implementation in Java. Check  this post  for time complexity. https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html The methods include: V put(K key, V value) boolean containsKey(Object key) V get(Object key) V remove(Object key) Set<K> keySet() etc Example import java.util.HashMap; import java.util.Map; public class HashMapExample {   public static void main(String[] args ) {     Map<String, Integer> map = new HashMap<String, Integer>();     map .put( "a" , 1);     map .put( "b" , 2);     map .put( "c" , 3);     System. out .println( map .get( "a" )); // 1     System. out .println( map .get( "z" )); // null     if ( map .containsKey( "b" )) {       System. out .println( map .get( "b" )); // 2     }     for (String key : map .keySet()) {       int val = map .get( key );       System. out .println( val ); // 1, 2, 3 (in undefined order)  

Java Data Structure Cheat Sheet

Average time complexity of data structures: Data structure Access (top) Access (key) Search Insertion Deletion Array O(1) O(1) O(N) O(N) O(N) Stack O(1) O(N) O(N) O(1) O(1) Queue O(1) O(N) O(N) O(1) O(1) Linked List O(1) O(N) O(N) O(1) O(1) Hash Table n/a O(1) O(1) O(1) O(1) Binary Search Tree O(1) O(log N) O(log N) O(log N) O(log N) Heap O(1) O(N) O(N) O(log N) O(log N) Each link is for a Java example.

Java Data Structure Cheat Sheet - Queue

Queue is an interface in Java. There are multiple implementation choices, but using LinkedList is common and performs as the usual queue as expected. https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html Main methods are: boolean add(E e) E element() E remove() and there exists the alternative ones as: boolean offer(E e) E peek() E poll() The first group throws an Exception whereas the second one returns "special value". They are all O(1). Example import java.util.LinkedList; import java.util.Queue; public class QueueExample {   public static void main(String[] args ) {     Queue<Integer> q = new LinkedList<Integer>();     q .add(1); // or q.offer(1)     q .add(2);     q .add(3);     System. out .println( q .element()); // 1. you can also use q.peek()     while (! q .isEmpty()) { // isEmpty() is from Collection       int n = q .remove(); // or q.poll()       System. out .println( n ); // 1, 2, 3     }   } }

kind (multi-node k8s cluster): Quick Start on Mac

This post shows an example usage of kind  on Mac. what is kind? kind lets you create a k8s cluster with multiple nodes on docker. You need docker & kubectl to run it. install % docker -v Docker version 20.10.5, build 55c4c88 % kubectl version ... v1.19.7 ... % brew install kind % kind --version kind version 0.11.0 one-node cluster You can create a one-node cluster by default. The initial creation may take a few minutes longer to load the image. % kind create cluster % kubectl get node NAME                 STATUS     ROLES                  AGE   VERSION kind-control-plane   NotReady   control-plane,master   30s   v1.21.1 % kind delete cluster multi-node cluster Passing a config file (--config) lets you create a cluster with multiple nodes. The following example will create 3 controle-planes & 3 workers. % cat kind.yaml  kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - role: control-plane - role: control-plane - role: worker - role: worker - role:

Java Data Structure Cheat Sheet - Stack

Stack exists as a class (not as an interface or abstract class) in Java. https://docs.oracle.com/javase/7/docs/api/java/util/Stack.html Here are the three main methods: E peek() E pop() E push(E item) They are all O(1). Example: import java.util.Stack; public class StackExample {   public static void main(String[] args ) {     Stack<Integer> s = new Stack<Integer>();     s .push(1); // add is also available as Vector     s .push(2);     s .push(3);     System. out .println( s .peek()); // 3     while (! s .empty()) { // isEmpty() is also available as Vector       int n = s .pop();       System. out .println( n ); // 3, 2, 1     }     // System.out.println(s.peek()); // java.util.EmptyStackException is called   } }

Assign Domain on Route53 to CloudFront

Image
In this post, I am going to assign a domain name (on Route53) to the website hosted on S3 thru CloudFront ( prev post ). user <-> Route53       -> CloudFront -> S3 Issue & Validate Certificate Console > Certificate Manager (ACM) > Request a certificate Add domain names > Domain name: *.YOUR_DOMAIN > Next Select validation method > DNS validation  > Next Add tags > Review Review > Confirm and request Validation > Create record in Route 53 > Continue The validation will take a few minutes. Add CNAME to CloudFront Console > CloudFront > [cloud-front-id] > Edit Alternate Domain Names: www.YOUR_DOMAIN SSL Certificate: Custom SSL Certificate: (select your certificate) > Yes, Edit Add A Record Console > Route53 > Hosted zone > YOUR_DOMAIN > Create record: Record name: www Recird type: A & AAAAA (Turn on Alias ) Route traffic to: Alias to CloudFront distribution , Select distribution > Create records Ref:  https://

Host Website on S3 thru CloudFront

In this post, I am going to describe how to host a website on S3, allowing the access from CloudFront for faster content distribution. user -> CloudFront -> S3 Create Bucket on S3 % mkdir web && cd web % echo 'Hello, World!' > index.html % aws s3 mb s3://YOUR_BUCKET_NAME % aws s3 cp index.html s3://YOUR_BUCKET_NAME Confirm that you cannot access the bucket directly. % curl https://s3.amazonaws.com/YOUR_BUCKET_NAME/index.html AccessDenied Create Distribution on CloudFront Console > CloudFront > Create Distribution > Get Started > Origin Domain Name: YOUR_BUCKET_NAME Restrict Bucket Access: Yes Origin Access Identity: Create a New Identity Grant Read Permissions on Bucket: Yes, Update Bucket Policy Default Root Object: index.html > Create Distribution This will take a few minutes. Access % aws cloudfront list-distributions | jq -r '.DistributionList.Items[0].DomainName' xxxxxxxxxxxxx.cloudfront.net % curl xxxxxxxxxxxxx.cloudfront.net Hello,